laravel
laravel copied to clipboard
Related resources are not included if relationship field is omitted using Sparse Fieldsets
JSON:API specification allows to omit a relationship field required for linkage in a compound document using sparse fieldsets:
Compound documents require “full linkage”, meaning that every included resource MUST be identified by at least one resource identifier object in the same document. These resource identifier objects could either be primary data or represent resource linkage contained within primary or included resources.
The only exception to the full linkage requirement is when relationship fields that would otherwise contain linkage data are excluded via sparse fieldsets.
https://jsonapi.org/format/#document-compound-documents
The package does not handle that edge case yet. If relationship field is omit using a sparse fieldset the related resources are not included even if include query parameter is present.
Let's assume this request successfully returns all posts together with their comments: GET /posts?include=comments
- If using a sparse fieldset, which omits the
commentsrelationship of posts, the related comments are not included. The API response with200 OKand the posts as primary data as ifincludequery parameter was not present. Such a request may look like this:GET /posts?include=comments&fields[posts]=title,summary&fields[comments]=title - If including the relationship field in the sparse fieldset the response is as expected. To do so the request given above must be changed like this (assuming that the relationship field of
postsresource is calledcomments):GET /posts?include=comments&fields[posts]=title,summary,comments&fields[comments]=title
This bug violated JSON:API specification as an API must return 400 Bad Request if not being able to process requested include query parameter. It must not ignore it. See https://jsonapi.org/format/#fetching-includes for details.
To be honest I don't see much use cases for using Sparse Fieldsets like this. I was just running into the issue due to a typo. Not supporting this edge case and returning a 400 Bad Request would be fine with me.
This seems to be a problem with the underlying neomerx/json-api encoder. There's an open issue on exactly this topic:
https://github.com/neomerx/json-api/issues/249
Under the hood, the include path is not ignored - the relationship will be eager loaded on the Eloquent model. It's the encoder that's deciding not to add it to the compound document when iterating through the data.
I'm not entirely sure what to do about this as I don't want to be making extensive changes to my fork of the neomerx package. I'm still hoping that neomerx will return at some point to maintain their package.
I think maybe leaving this issue open for the moment is fine. There's an easy workaround, which is to just make sure the relationship is also listed in the sparse fieldsets (which is a more logical request anyway).