Null relationship object for non-existent relationship

Hi,

I am working on a project which extensively uses JSON:API specifications.

The client requests a compound document using the include keyword.
The server successfully responds with a valid compound document having “full linkage”.

The “relationships object” contains “relationship object” for all the direct relationships for the document’s primary data.
Each “relationship object” only contains the data section, i.e. Resource Linkage.

The client makes the same request multiple times (polling) to stay updated with the state of the data on the server.
The relationships that the primary data has at any give point might change depending upon the state of the resource.

If the primary data has a relationship, it is present in the server response as a “relationship object” having Resource Linkage.
If the primary data does not have a relationship, that “relationship object” itself is absent from the “relationships object”.

It can happen that the response from server contained a specific “relationship object” at a specific time, and did not contain that “relationship object” at a later time.

Now, the client (using Ember) is unable to process the removal of this “relationship object” and continues to show the stale relationship.

Client is of the opinion that the server should have sent a “relationship object” (with null/empty-array Resource Linkage) for the absent relationship(s), quoting:

Resource linkage MUST be represented as one of the following:

  • null for empty to-one relationships.
  • an empty array () for empty to-many relationships.
  • a single resource identifier object for non-empty to-one relationships.
  • an array of resource identifier objects for non-empty to-many relationships.

We require clarity on the interpretation of the above.
I think the above text implies that if a resource linkage is present in the “relationship object”, it must be represented in one of the above specified ways.
It does not however anyhow imply that a null/empty-array Resource Linkage is a must for non-existent relationship(s).

Also, going through the below sections, I don’t find any statement implying that “relationship object” (with null/empty-array Resource Linkage) is mandatory for non-existent relationship(s):

The compound object returned from the server always conforms to the “full linkage” specification.

Does JSOP:API require the “relationships object” to mandatorily contain “relationship object” (with null/empty-array Resource Linkage) for non-existent relationship(s)?

Hello,

I’m not fully sure what you mean by “non-existent relationship(s”). But I have an idea.

Let’s see different resource objects to understand what information the client can derive about it.

Array with resource identifier objects

{
  "type": "posts",
  "id": "1",
  "relationships": {
    "comments": {
     "data": [
       { "type": "comments", "id": "2" }
     ],
     "links": {
      "self": "/posts/1/comments"
     }
   }
  }
}

The client can derive the following information:

  • The resource type posts has a relationship comments.
  • The comments relationship is a has-many relationship.
  • The related comments could be fetched with a GET request to /posts/1/comments.
  • The post with ID 1 has a comment with the ID 2.

Empty array

{
  "type": "posts",
  "id": "1",
  "relationships": {
    "comments": {
     "data": [],
     "links": {
      "self": "/posts/1/comments"
     }
   }
  }
}

The client can derive the following information:

  • The resource type posts has a relationship comments.
  • The comments relationship is a has-many relationship.
  • The related comments could be fetched with a GET request to /posts/1/comments.
  • The post with ID 1 does not have any comment.

No resource linkage

{
  "type": "posts",
  "id": "1",
  "relationships": {
    "comments": {
     "links": {
      "self": "/posts/1/comments"
     }
   }
  }
}

The client can derive the following information:

  • The resource type posts has a relationship comments.
  • The related comments could be fetched with a GET request to /posts/1/comments.

The client does not know the type of the relationship (has-many or has-one) nor does it know if any resources are attached to it currently.

No entry in relationships object at all

{
  "type": "posts",
  "id": "1",
  "relationships": {}
  }
}

The client knows nothing about the comments relationship. Not even that the relationship exists.

Summary

All the examples above are valid resource objects. Unless the client requests the inclusion of a relationship explicitly, all of them would be valid responses. But there is a big difference between not including resource linkage for a relationship or including it with an empty array (has-many) or null (has-one). A client can only knows that the relationship is empty, if resource linkage is included. A client must not derive any meaning from a field not being present in a resource object.

Quick one - the Empty Array example is incorrect right?
Shouldn’t it be:

{
  "type": "posts",
  "id": "1",
  "relationships": {
    "comments": {
     "data": [],
     "links": {
      "self": "/posts/1/comments"
     }
   }
  }
}

Yes. Good catch. I fixed it.