Skip to content

Filtering/querying (deep) relationships - a proposal for a syntax #1445

@cmeeren

Description

@cmeeren

(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 type author
  • Resource author has relationship articles which is to-many article
  • Resource article has attribute isDraft: 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 with isDraft=true"
  • filter[articles][isDraft]=true means "for any included articles from the articles relationship, only return those with isDraft=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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    profileRelated to existing and proposed profiles as well as profiles in general

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      pFad - Phonifier reborn

      Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

      Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


      Alternative Proxies:

      Alternative Proxy

      pFad Proxy

      pFad v3 Proxy

      pFad v4 Proxy