-
Notifications
You must be signed in to change notification settings - Fork 890
Description
(Previously posted at discuss.jsonapi.com.)
JSON:API currently lacks a standard for filtering/querying data included through relationships, as opposed to GraphQL which has this firmly specified. (Related issue: #1272)
Consider the following API:
GET /authors
to get all resources of typeauthor
- Resource
author
has relationshiparticles
which is to-manyarticle
- Resource
article
has attributeisDraft: boolean
Now consider the following request:
- "Give me all authors who have draft articles, and include their draft articles".
There are two filters here:
- The filter on the author list (filtering on a related resource's attribute)
- The filter on the included articles
Here is a syntax that might be able to confer the necessary distinction:
GET /authors
?filter[articles.isDraft]=true
&filter[articles][isDraft]=true
&include=articles
The meaning of the two filters would be:
filter[articles.isDraft]=true
means "only return authors who have articles withisDraft=true
"filter[articles][isDraft]=true
means "for any included articles from thearticles
relationship, only return those withisDraft=true
"
In other words:
- The first (of two) pair of brackets indicate what to filter (if not present, filter top-level data)
- The second (or only) pair of brackets indicate how to filter, using dot notation for filtering on related resources
As far as I can see, this syntax is general enough to be nested artibrarily on any level. For example, filter[articles.comments][author.name]=John&include=articles.comments
means "for each article, include only those comments whose author has name=John
"
Update: It occurred to me that this proposal can also work with pagination of relationships:
GET /authors
?include=articles
&page[articles][offset]=10
&page[articles][limit]=5
The above would return all authors and include a subset of each of their articles according to the pagination parameters.
Furthermore, it can work for sparse fieldsets:
GET /authors
?include=articles.comments.author
&fields[articles.comments.author][author]=name
&fields[articles.comments.author][anonymousUser]=firstName
In the above request, the top-level (i.e. primary data) authors would have all fields, while the included authors for each comment (at the end of the include hierarchy), would either have the field name
(if type is author
) or firstName
(if type is anonymousUser
).
Does this make sense? Could this syntax be a clear, general, and consistent way to support filters on nested relationships? Could this be part of the JSON-API spec, or a recommendation?