jsonapi-converter icon indicating copy to clipboard operation
jsonapi-converter copied to clipboard

Relationship parsing logic relies on optional resource linkage

Open emetsger opened this issue 8 years ago • 1 comments

Summary

In RelationshipResolver, the method isCollection(JsonNode) is used a priori to determine whether or not a relationship link will return an array or an object. This cannot be done a priori if resource linkages (optional per the JSON API spec) are absent from a relationship.

See this test, which fails on develop.

Example JSON

If the jsonapi-converter is parsing the JSON below, and attempts resolve the related relationship (http://example.com/articles/1/comments):

{
  "data": [{
    "type": "articles",
    "id": "1",
    "attributes": {
      "title": "JSON API paints my bikeshed!"
    },
    "relationships": {
      "comments": {
        "links": {
          "related": "http://example.com/articles/1/comments"
        }
      }
    }
  }]
}

And the JSON returned by http://example.com/articles/1/comments is this:

{
  "data": [
    {
      "type": "comments",
      "id": "5",
      "attributes": {
        "body": "First!"
      }
    },
    {
      "type": "comments",
      "id": "12",
      "attributes": {
        "body": "I like XML better"
      }
    }
  ]
}

Parsing of the http://example.com/articles/1/comments response will fail. Note that there is no resource linkage in the initial JSON document (the one representing articles). Had the initial JSON document contained a resource linkage in the comments relationship like so:

"relationships": {
      "comments": {
        "links": {
          "related": "http://example.com/articles/1/comments"
        },
        "data": [
          { "type": "comments", "id": "5" },
          { "type": "comments", "id": "12" }
        ]
      }
    }

Parsing of the http://example.com/articles/1/comments document would succeed.

Because resource linkages are optional per the specification, the initial JSON document, sans resource linkage, should result in a successful response.

Discussion

isCollection(JsonNode) introspects on the relationship object and uses the resource linkage as hint (resource linkages for relationships must properly represent to-many relationships as arrays, and to-one relationships as objects).

However, resource linkages are not required to be present in a relationship:

A “relationship object” MUST contain at least one of the following:

links: a links object containing at least one of the following:
  * self: a link for the relationship itself (a “relationship link”). This link allows the client to directly manipulate the relationship. For example, removing an author through an article’s relationship URL would disconnect the person from the article without deleting the people resource itself. When fetched successfully, this link returns the linkage for the related resources as its primary data. (See Fetching Relationships.)
  * related: a related resource link
data: resource linkage
meta: a meta object that contains non-standard meta-information about the relationship.

So resource linkages, if present, may be used a priori to determine the to-many or to-one-ness of a relationship, but if the resource linkage is not present, then the parsing logic must be prepared to parse a collection or an object after dereferencing the relationship.

emetsger avatar May 04 '16 14:05 emetsger

69b1945 contains a unit test demonstrating the issue.

emetsger avatar May 04 '16 14:05 emetsger