Achieve compatability with JSON:API 1.1
Art4 opened this issue · 1 comments
Backward incompatibilities between 1.0
and 1.1
BC for JSON-API is defined in section 1 of the spec:
1.) Status
This page presents an archived copy of JSON:API version 1.0. None of the normative text on this page will change. While 1.0 is no longer the latest version of JSON:API, new versions will remain compatible with this one, as JSON:API uses a never remove, only add strategy.
Even if these two sentences seem to be mutually exclusive see this comment:
In the schema world, those two statements are mutually exclusive.
I get that, so I understand why they seem odd. But, in the protocol design world, this apparent "contradiction" is actually a logical prerequisite for extensibility. Please take a look at this great article if you have a second. Basically, it proves that you need to make the set of legally-producable messages smaller than the set of legally consumable messages (which is what
additionalProperties: true
does) if you want protocol extensibility. So this decision isn't some arbitrary quirk of the spec text or esoteric schema point: it's a critical part of the design!
There seems to be some BC breaks between 1.0
and 1.1
. I will document them here so we can report them back and eventually find a way to handle them.
Allow extension member to be the only member in top-level document
Changes between 1.0
and 1.1
(simplified)
### <a href="#document-top-level" id="document-top-level" class="headerlink"></a> Top Level
A JSON object **MUST** be at the root of every JSON:API request and response
document containing data. This object defines a document's "top level".
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](#errors).
* `meta`: a [meta object][meta] that contains non-standard
meta-information.
+ * a member defined by an applied [extension](#extensions).
Problem
The following content is valid 1.1
, but is backward incompatible with 1.0
because data
, errors
and meta
are missing:
POST /operations HTTP/1.1
Host: example.org
Content-Type: application/vnd.api+json;ext="https://jsonapi.org/ext/atomic"
Accept: application/vnd.api+json;ext="https://jsonapi.org/ext/atomic"
{
"atomic:operations": [{
"op": "add",
"href": "/blogPosts",
"data": {
"type": "articles",
"attributes": {
"title": "JSON API paints my bikeshed!"
}
}
}]
}
Allow extension member to be the only member in relationship object
Changes between 1.0
and 1.1
(simplified)
##### <a href="#document-resource-object-relationships" id="document-resource-object-relationships" class="headerlink"></a> Relationships
The value of the `relationships` key **MUST** be an object (a "relationships
object"). Each member of a relationships object ("relationships") represents
a "relationship" from the [resource object][resource objects]
in which it has been defined to other resource objects.
Relationships may be to-one or to-many.
A relationship's name is given by its key. The value at that key **MUST** be an
object ("relationship object").
<a id="document-resource-object-relationships-relationship-object"></a>
A "relationship object" **MUST** contain at least one of the following:
* `links`: a [links object][links] 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][resource linkage]
for the related resources as its primary data.
(See [Fetching Relationships](#fetching-relationships).)
* `related`: a [related resource link]
* a member defined by an applied [extension](#extensions).
* `data`: [resource linkage]
* `meta`: a [meta object][meta] that contains non-standard meta-information about the
relationship.
+ * a member defined by an applied [extension](#extensions).
Problem
The following content is valid 1.1
, but is backward incompatible with 1.0
because links
, data
and meta
are missing:
POST /articles HTTP/1.1
Host: example.org
Content-Type: application/vnd.api+json;ext="https://example.org/ext/example"
Accept: application/vnd.api+json;ext="https://example.org/ext/example"
{
"data": {
"type": "articles",
"attributes": {
"title": "JSON API paints my bikeshed!"
},
"relationships": [
{
"example:color": {
"name": "red",
}
}
]
}
}
Allow extension member to be the only member in relationship links object
Changes between 1.0
and 1.1
(simplified)
##### <a href="#document-resource-object-relationships" id="document-resource-object-relationships" class="headerlink"></a> Relationships
The value of the `relationships` key **MUST** be an object (a "relationships
object"). Each member of a relationships object ("relationships") represents
a "relationship" from the [resource object][resource objects]
in which it has been defined to other resource objects.
Relationships may be to-one or to-many.
A relationship's name is given by its key. The value at that key **MUST** be an
object ("relationship object").
<a id="document-resource-object-relationships-relationship-object"></a>
A "relationship object" **MUST** contain at least one of the following:
* `links`: a [links object][links] 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][resource linkage]
for the related resources as its primary data.
(See [Fetching Relationships](#fetching-relationships).)
* `related`: a [related resource link]
+ * a member defined by an applied [extension](#extensions).
* `data`: [resource linkage]
* `meta`: a [meta object][meta] that contains non-standard meta-information about the
relationship.
* a member defined by an applied [extension](#extensions).
Problem
The following content is valid 1.1
, but is backward incompatible with 1.0
because self
and related
are missing:
POST /articles HTTP/1.1
Host: example.org
Content-Type: application/vnd.api+json;ext="https://example.org/ext/example"
Accept: application/vnd.api+json;ext="https://example.org/ext/example"
{
"data": {
"type": "articles",
"attributes": {
"title": "JSON API paints my bikeshed!"
},
"relationships": [
{
"links": [
"example:link": {
"href": "https://example.org",
}
]
}
]
}
}