Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTTP PATCH: Handling arrays, deletion, and nested key creation

Tags:

I'm looking for a practical guide to implementing the PATCH verb for partial updates of a noun in a RESTful api using JSON. Understanding that PATCH is for partial updates, we lack still standardization around the syntax for deleting keys, creating or updating nested keys, and arrays.

Let's say I GET an object:

// GET users/42 {   id: 42,   name: 'SimpleAsCouldBe',   city: 'San Francisco',   roles: ['viewer','editor'],   posts: {     '01': {},     '02': {},   } } 

...Then I want to update it:

// PATCH users/42 {   name: 'SimpleGuy',                   // CLEAR:   update the key's value   email: '[email protected]',             // CLEAR:   add the new key   city: null                           // UNCLEAR: delete the key?   roles: ['owner'],                    // UNCLEAR: replace the whole array?   posts: {     '02': { title:'how to pop lock' }, // CLEAR:  update nested key     '03': { title:'how to salsa' }     // CLEAR:  create new nested key   }   notes: {     '01': { title: 'a note title' }    // CLEAR (but disallowed?): create wrapping key   } } 

The PATCH rfc says no to creating nested keys. This is a spec bug, I think, because creating a nested key is non-ambiguous.

I could send a full object diff, like this library generates, but this makes the clear case of adding or updating a key more verbose.

How do I handle arrays, deletion, and nested keys in a lean way with HTTP PATCH?

like image 907
SimplGy Avatar asked Apr 02 '14 18:04

SimplGy


1 Answers

The spec clearly details how to format the JSON body of a PATCH request. You're using a totally different format. Given that, I'm not surprised at all that there is ambiguity. The body should look something like:

   [      { "op": "replace", "path": "/name", "value": "SimpleGuy" },      { "op": "add", "path": "/email", "value": "[email protected]" },      { "op": "replace", "path": "/city", "value": null },      { "op": "replace", "path": "/roles", "value": [ "owner" ] },      { "op": "add", "path": "/posts/02/title", "value": "how to pop lock" },      { "op": "add", "path": "/posts/", "value": "03" },      { "op": "add", "path": "/posts/03/title", "value": "how to salsa" },      { "op": "add", "path": "/notes", "value": { "title": "a note title" } }    ] 

Go back and read the spec. It even gives examples which address most of your questions.

like image 158
Eric Stein Avatar answered Oct 11 '22 09:10

Eric Stein