Update Endpoints (#134)
PATCH
Endpoints used to update an entity should use PATCH
as the verb rather than PUT
. This allows for partial updates of the resource. (We require users to use the POST
endpoint for entity creation).
PATCH
endpoints must implement a derivative of JSON Merge Patch as defined by RFC 7396 with the following clarifications:
- If the
Content-Type
request header is not application/json
, the PATCH
operation must return 400.
- If an unknown field is provided, the entire
PATCH
operation must return 400 with the unknown field described in the invalid_parameters
extension.
- If a read-only field is provided, the entire
PATCH
operation must return 400 with the read-only field described in the invalid_parameters
extension.
- Nested object fields MUST be recursively patched.
- If the value of a field in the patch document is set to
null
and...
- If the property is non-required, then remove the property from the object.
- If the property is within a schema-less object, then remove the property from the object.
- If a property is required and nullable, then set the value of the property to
null
.
- If a property is required and non-nullable, then return 400 with the required property described in the
invalid_parameters
extension.
Examples
Given the following example JSON document:
{
"a": "b",
"c": {
"d": "e",
"f": "g"
}
}
If we apply the following changes:
PATCH /target HTTP/1.1
Host: example.org
Content-Type: application/json
{
"a":"z",
"c": {
"f": null
}
}
The preferred JSON response would include any nullified fields that are defined in the entity's schema:
{
"a": "z",
"c": {
"d": "e",
"f": null
}
}
An acceptable JSON response would be to leave out null fields, but this should be the exception, not the rule, for Kong APIs:
{
"a": "z",
"c": {
"d": "e"
}
}
Detailed Example
Given the following JSON document:
{
"attr_1": "Sample Entity",
"attr_2": false,
"attr_3": {
"sub_attr_1": "red",
"sub_attr_2": 1337
},
"tags": [
"tag_1",
"tag_2"
],
"labels": {
"key_1": "val_1",
"key_2": "val_2"
}
}
-
Modifying a value:
Change "Sample Entity"
to "Updated Entity"
:
{ "attr_1": "Updated Entity" }
-
Adding a new field:
Add "attr_4": "New Attribute"
:
{ "attr_4": "New Attribute" }
-
Modifying a nested field:
Change "sub_attr_1"
to "blue
" in "attr_3"
:
{ "attr_3": { "sub_attr_1": "blue" } }
-
Setting a nullable field to a null
value:
{ "attr_3": null }
-
Replacing an array:
Replace the tags
array with a new one containing "tag_3"
and "tag_4"
:
{ "tags": ["tag_3", "tag_4"] }
Replace the tags
array with an empty array:
{ "tags": [] }
-
Modifying a field in an object:
Change label "key_1": "val_1"
to the "key_1": "val_one"
:
{ "labels": { "key_1": "val_one" } }
-
Adding a new field to an object:
Add a new label "key_3": "val_3"
to the labels
object:
{ "labels": { "key_3": "val_3" } }
-
Deleting a field from an object:
Remove the label "key_2": "val_2"
from the labels
object:
{ "labels": { "key_2": null } }
Remove all labels from the labels
object:
{ "labels": { "key_1": null, "key_2": null } }
-
No op:
The following patch requests perform no updates.
{}
{ "labels": {} }
{ "attr_3": {} }
hello
Exceptions
PUT
In exceptional cases, PUT
endpoints may be provided instead of PATCH
. PUT
endpoints are advised when the full entity representation is required to validate the data sent in the request (ex: conditional entity representations based on a type
property discriminator).