How to get relationship data without including them?

Hey there, we want to use JSON:API but at this point we struggle with the specification.

I want to make the following request:

GET /articles

The response should include the relationships data (id and type). I couldn’t figure out if this is either forbidden, allowed or optional.

Is there any way to force the inclusion of the data in the relationships without actually include them?
I do not want to make the following request:

GET /articles?include=author

This would create a included object with every field on the author. I could use sparse fieldsets:

GET /articles?include=author&fields[author]=id

This would prevent every field to be included but all I want is the linkage data (id, type) for the relations and no further info.

Is there any special way to achieve this?

1 Like

The JSON:API specification does not allow a client to request usage of resource linkage for a relationship without requesting the related resources to be included.

It’s up to the server implementation to decide if it provides related resource links or resource linkage data or both for a specific relationship. Only if a related resource is included resource linkage must be used.

A server may even decide to not include the relationship field by default. As pointed out in the question you can force the server to include that field using Sparse Fieldsets.

In general it’s considered good practice to

  • provide related resource links for all relationships,
  • include resource linkage data only if
    • the related resource is included or
    • it does not cause additional load for the server.
1 Like

This would work as I understand the spec. You can (maybe should) even remove the id part from it. The type and id are not part of the fields (JSON:API — Specification v1.1 (Still in Development)) of a resource.

However, good to know that the sparse fieldset work with the type of the (related) data, not the relationship name of it. Thus if the type of the author relationship is human you need to use human for the sparse fieldset.

Thus /articles?include=author&fields[human]= would include the relationship but not the related data. Note the author does need to be present in the included array, but without any extra data.

{
    "data": [
        {
            "type": "article",
            "id": "1",
            "attributes": {
                "title": "foo"
            },
            "relationships": {
                "author": {
                    "data": {
                        "type": "human",
                        "id": "42"
                    }
                }
            }
        },
        {
            "type": "article",
            "id": "2",
            "attributes": {
                "title": "bar"
            },
            "relationships": {
                "author": {
                    "data": {
                        "type": "human",
                        "id": "42"
                    }
                }
            }
        }
    ],
    "included": [
        {
            "type": "human",
            "id": "42",
            "attributes": {}
        }
    ],
    "links": {
        "self": "/articles?include=author&fields[human]="
    }
}

Another option is indeed that the server decides to not include full resources but only resource identifiers. Then you can also avoid having the included array and the sparse fieldset wouldn’t be needed anymore.