JSON Patch Extension
Status
Extensions are an experimental feature and should be considered a work in progress. There is no official support for extensions in the base JSON API specification.
Introduction
The “JSON Patch extension” is an official extension of the JSON API specification. It provides support for modification of resources with the HTTP PATCH method [RFC5789] and the JSON Patch format [RFC6902].
For the sake of brevity, operations requested with PATCH and conforming
with JSON Patch will be called “Patch operations”.
Servers and clients MUST negotiate support for and use of the JSON Patch
extension as described in the base specification using
jsonpatch as the name of the extension.
Patch Operations
Patch operations MUST be sent as an array to conform with the JSON Patch format. A server MAY limit the type, order, and count of operations allowed in this top level array.
Request URLs and Patch Paths
The request URL and each Patch operation’s path are complementary and
MUST combine to target a particular resource, collection, attribute, or
relationship.
If a server supports the Patch extension, it MUST allow Patch operations at any resource or relationship URLs that accept POST, PATCH, or DELETE requests.
Patch operations MAY also be allowed at the root URL of an API. In this
case, every path within a Patch operation MUST include the full
resource path relative to the root URL. This allows for general “fire hose”
updates to any resource or relationship represented by an API. As stated
above, a server MAY limit the type, order, and count of bulk operations.
Creating Resources
To create a resource, request an add operation with a path that points
to the end of its corresponding resource collection (/-). The value
should contain a resource object.
For example, a new photo could be created with the following request:
PATCH /photos HTTP/1.1
Content-Type: application/vnd.api+json; ext=jsonpatch
Accept: application/vnd.api+json; ext=jsonpatch
[
{
"op": "add",
"path": "/-",
"value": {
"type": "photos",
"attributes": {
"title": "Ember Hamster",
"src": "http://example.com/images/productivity.png"
}
}
}
]
Updating Attributes
To update an attribute, perform a replace operation with the attribute’s
name specified by the path.
For instance, the following request should update just the src property of the
photo at /photos/1:
PATCH /photos/1 HTTP/1.1
Content-Type: application/vnd.api+json; ext=jsonpatch
Accept: application/vnd.api+json; ext=jsonpatch
[
{ "op": "replace", "path": "/src", "value": "http://example.com/hamster.png" }
]
Updating Relationships
To update a relationship, send an appropriate Patch operation to the relationship’s URL.
A server MAY also support relationship updates at a higher level, such
as the resource’s URL or the API’s root URL. As discussed above, the request
URL and each Patch operation’s path must be complementary and combine to
target a particular relationship’s URL.
Updating To-One Relationships
To update a to-one relationship, perform a replace operation with a URL
and path that targets the relationship. The value MUST be a
resource identifier object or null, to remove the relationship.
For instance, the following request should update the author of an article:
PATCH /article/1/relationships/author HTTP/1.1
Content-Type: application/vnd.api+json; ext=jsonpatch
Accept: application/vnd.api+json; ext=jsonpatch
[
{ "op": "replace", "path": "", "value": {"type": "people", "id": "1"} }
]
To remove a to-one relationship, perform a replace operation on the
relationship to change its value to null. For example:
PATCH /article/1/relationships/author HTTP/1.1
Content-Type: application/vnd.api+json; ext=jsonpatch
Accept: application/vnd.api+json; ext=jsonpatch
[
{ "op": "replace", "path": "", "value": null }
]
Updating To-Many Relationships
A server MUST respond to Patch operations that target a to-many relationship URL as described below.
For all operations, the value MUST contain an object that contains
an array of resource identifier objects or an empty array, to remove all
elements of the relationship.
If a client requests a replace operation to a to-many relationship URL, the
server MUST either completely replace every member of the relationship,
return an appropriate error response if some resources can not be found or
accessed, or return a 403 Forbidden response if complete replacement is
not allowed by the server.
For example, the following request replaces every tag for an article:
PATCH /photos/1/relationships/tags HTTP/1.1
Content-Type: application/vnd.api+json; ext=jsonpatch
Accept: application/vnd.api+json; ext=jsonpatch
[
{
"op": "replace",
"path": "",
"value": [
{ "type": "tags", "id": "2" },
{ "type": "tags", "id": "3" }
]
}
]
To add an element to a to-many relationship, request an add operation that
targets the relationship’s URL. Because the operation is targeting the end of a
collection, the path must end with /-.
In the following example, the comment with ID 123 is added to the list of
comments for the article with ID 1:
PATCH /articles/1/relationships/comments HTTP/1.1
Content-Type: application/vnd.api+json; ext=jsonpatch
Accept: application/vnd.api+json; ext=jsonpatch
[
{
"op": "add",
"path": "/-",
"value": [
{ "type": "comments", "id": "123" }
]
}
]
To remove a to-many relationship, perform a remove operation that targets
the relationship’s URL.
In the following example, comments with IDs of 5 and 13 are removed
from the list of comments for the article with ID 1:
PATCH /articles/1/relationships/comments HTTP/1.1
Content-Type: application/vnd.api+json; ext=jsonpatch
Accept: application/vnd.api+json; ext=jsonpatch
[
{
"op": "remove",
"path": "",
"value": [
{ "type": "comments", "id": "5" },
{ "type": "comments", "id": "13" }
]
}
]
Deleting a Resource
To delete a resource, perform a remove operation with a URL and path
that targets the resource.
For instance, photo "1" might be deleted with the following request:
PATCH /photos/1 HTTP/1.1
Content-Type: application/vnd.api+json; ext=jsonpatch
Accept: application/vnd.api+json; ext=jsonpatch
[
{ "op": "remove", "path": "" }
]
Responses
204 No Content
A server MUST return a 204 No Content status code in response to a
successful Patch operation in which the client’s current attributes remain up to
date.
200 OK
If a server accepts an update but also changes the resource(s) in other ways
than those specified by the request (for example, updating the updatedAt
attribute or a computed sha), it MUST return a 200 OK response as well
as a representation of the updated resources.
The server MUST specify a Content-Type header of application/vnd.api+json;
ext=jsonpatch. The body of the response MUST contain an array of JSON objects,
each of which MUST conform to the JSON API media type
(application/vnd.api+json). Response objects in this array MUST be in
sequential order and correspond to the operations in the request document.
For instance, a request may create two photos in separate operations:
PATCH /photos HTTP/1.1
Content-Type: application/vnd.api+json; ext=jsonpatch
Accept: application/vnd.api+json; ext=jsonpatch
[
{
"op": "add",
"path": "/-",
"value": {
"type": "photos",
"attributes": {
"title": "Ember Hamster",
"src": "http://example.com/images/productivity.png"
}
}
},
{
"op": "add",
"path": "/-",
"value": {
"type": "photos",
"attributes": {
"title": "Mustaches on a Stick",
"src": "http://example.com/images/mustaches.png"
}
}
}
]
The response would then include corresponding JSON API documents contained within an array:
HTTP/1.1 200 OK
Content-Type: application/vnd.api+json; ext=jsonpatch
[
{
"data": [{
"type": "photos",
"id": "123",
"attributes": {
"title": "Ember Hamster",
"src": "http://example.com/images/productivity.png"
}
}]
}, {
"data": [{
"type": "photos",
"id": "124",
"attributes": {
"title": "Mustaches on a Stick",
"src": "http://example.com/images/mustaches.png"
}
}]
}
]
Errors
A server MAY return error objects that correspond to each operation. The
body of the response MUST contain an array of JSON objects, which
MUST be in sequential order and correspond to the operations in the
request document. Each response object SHOULD contain only error objects
keyed by errors, since no operations can be completed successfully when
any errors occur. Error codes for each specific operation SHOULD be
returned in the status member of each error object.