Presence of data in request and response

Hello,

the specification seems to be quite clear that a data JSON attribute named data should be present in JSON response and request body.

A document MUST contain at least one of the following top-level members:

  • data : the document’s “primary data”
  • errors : an array of error objects
  • meta : a meta object that contains non-standard meta-information.

Looking into the reference gives a couple of incomplete and seemingly complete example responses. Therefore I am a bit confused if data should actually be always present.

Assume following example:

{
	"data": {
		"attributes": {
			"name": "First Pool",
			"description": "A good pool",
			"city": "Berlin",
			"country": "Germany",
			"active": true
		},
		"id": "5c071fae-01fa-4f18-b692-7bc6fc98331f",
		"links": {
			"self": "/pools/5c071fae-01fa-4f18-b692-7bc6fc98331f"
		},
		"relationships": {
			"user": {
				"data": {
					"id": "d315dbe2-5f3a-4772-b130-7de54c5cfea5",
					"type": "users"
				},
				"links": {
					"self": "/pools/5c071fae-01fa-4f18-b692-7bc6fc98331f/relationships/user",
					"related": "/pools/5c071fae-01fa-4f18-b692-7bc6fc98331f/user"
				}
			}
		},
		"type": "pools"
	},
	"links": {
		"self": "/pools/5c071fae-01fa-4f18-b692-7bc6fc98331f"
	}
}

What response for /pools/5c071fae-01fa-4f18-b692-7bc6fc98331f/relationships/user is the correct one?

Response A

# GET /pools/5c071fae-01fa-4f18-b692-7bc6fc98331f/relationships/user

"data": {
	"id": "d315dbe2-5f3a-4772-b130-7de54c5cfea5",
	"type": "users"
},
"links": {
	"self": "/pools/5c071fae-01fa-4f18-b692-7bc6fc98331f/relationships/user",
	"related": "/pools/5c071fae-01fa-4f18-b692-7bc6fc98331f/user"
}

Response B (Note: it could also only contain links attribute, as data is not mandatory)

# GET /pools/5c071fae-01fa-4f18-b692-7bc6fc98331f/relationships/user

"data": {
	"data": {
		"id": "d315dbe2-5f3a-4772-b130-7de54c5cfea5",
		"type": "users"
	},
	"links": {
		"self": "/pools/5c071fae-01fa-4f18-b692-7bc6fc98331f/relationships/user",
		"related": "/pools/5c071fae-01fa-4f18-b692-7bc6fc98331f/user"
	}
},
"links": {
	"self": "/pools/5c071fae-01fa-4f18-b692-7bc6fc98331f/relationships/user",
}

Thanks for your feedback.

Before addressing the structure of your response, let’s look at your endpoint. If there is a relationship between a pool resource and a single user resource, then the more RESTful design would be simply

GET /pools/{poolResourceId}/user

Now as for your comment, “Therefore I am a bit confused if data should actually be always present”, the specification says “at least one of the following top-level members.” That does not mean a document must always contain data. The document could contain only errors, or data and meta, or only meta, etc. Note that the specification also says "The members data and errors MUST NOT coexist in the same document.

Later in the specification, it says:

Primary data MUST be either:

Your endpoint is requesting a single resource, user, associated with the pool resource. Your example A is the correctly-formed document as the primary data object contains a single resource identifier object. Example B is not correctly formed. Nesting another data object within is not accurate to the specification.

Ok, of course data should must not always be present. This was maybe a bit unclear written.

But Response A is a relationship object which in this case contains a data attribute. Specification says

https://jsonapi.org/format/#document-resource-object-relationships

The value of the relationships key MUST be an object (a “relationships object”). Members of the relationships object (“relationships”) represent references from the resource object in which it’s defined to other resource objects.

Relationships may be to-one or to-many.

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.
    • related : a related resource link
  • data : resource linkage
  • meta : a meta object that contains non-standard meta-information about the relationship.

So if data is not mandatory the following response would be a valid relationship object but not a valid document.

# GET /pools/5c071fae-01fa-4f18-b692-7bc6fc98331f/relationships/user

"links": {
	"self": "/pools/5c071fae-01fa-4f18-b692-7bc6fc98331f/relationships/user",
	"related": "/pools/5c071fae-01fa-4f18-b692-7bc6fc98331f/user"
}

Am I wrong here?

That is not a valid message.

The relevant section of the spec says –

 A document MUST contain at least one of the following top-level members:

    data: the document’s “primary data”
    errors: an array of error objects
    meta: a meta object that contains non-standard meta-information.

Your message does not meet the above criteria.

The section of the spec you are quoting about the relationships key is not relevant to what you’re trying to do. Relationships are part of the json document and are not intended to be entities like you have modeled them with /relationships

The spec is confusing and is not written clearly!