4

I can't find samples on the way to use JSON Patch to update a collection. In fact, I want to use a method PATCH on a collection REST resource in order to update the associated collection without sending again the whole collection. I wonder if JSON Patch could match to describe the operations to do: mainly add elements or remove elements. Elements are complex, meaning that they aren't primitive elements.

Below there are some more details. Let's take the sample of a resource contacts:

GET /contacts
[
  {
    "id": "1",
    "lastName": "Last name 1",
    "firstName": "First name 1"
  },
  {
    "id": "2",
    "lastName": "Last name 2",
    "firstName": "First name 2"
  },
  {
    "id": "3",
    "lastName": "Last name 3",
    "firstName": "First name 3"
  },
  (...)
]

Here is the PATCH request I would like to use but I'm not sure that is JSON Patch compliant:

PATCH /contacts
[
  {
    "op": "add", "value": {
      "firstName": "my first name",
      "lastName": "my last name"
    }
  },
  {
    "op": "remove", "path": "id=='1'"
  }
]

My main issue is how to identify the element to delete based on its field id. Is there dedicated expression for this? I thought about something like: id=='1'.

Last question: is the response content targeted by JSON Patch?

Thanks very much by avance for your help! Thierry

Thierry Templier
  • 198,364
  • 44
  • 396
  • 360

1 Answers1

3

You should be able to simply use the path for the resource to be deleted.

PATCH /contacts
[
  {
    "op": "add",
    "path": "/-",
    "value": {
      "firstName": "my first name",
      "lastName": "my last name"
    }
  },
  {
    "op": "remove", 
    "path": "/0"
  }
]

Looking around, there seems to be some confusion about this, but the standard says "The "remove" operation removes the value at the target location" with example:

{ "op": "remove", "path": "/a/b/c" }
Community
  • 1
  • 1
mahemoff
  • 44,526
  • 36
  • 160
  • 222
  • Any hints about the patch response? – Thierry Templier Apr 29 '15 at 08:19
  • The standard doesn't say. It's supposed to be an atomic transaction, so technically no info needs to be returned as the client can assume either everything changed or nothing changed. You'd normally want to at least include error messages for each op, if errors did occur. – mahemoff Apr 29 '15 at 08:26
  • In fact, I see two things that could be returned in the response ;-) : the identifier of created element (in the case of auto-generated pk) and the validation errors. We have a noSQL backend behind the API so we don't have transactions... – Thierry Templier Apr 29 '15 at 08:49
  • True, the IDs should be returned (and possibly more) for new resources. – mahemoff Apr 29 '15 at 09:26
  • REST APIs should ideally be implementation-agnostic; even though your DB doesn't support transactions, the contract is still to make it atomic. It's probably overkill to manually roll back; but you could approximate atomicity by pre-validating all sections before changing anything. (BTW some NoSQLs do support transactions, it's just less common.) – mahemoff Apr 29 '15 at 09:29
  • Yes, I definitevely agreed with that ;-) – Thierry Templier Apr 29 '15 at 09:47
  • According to http://jsonapi.org/extensions/jsonpatch/ a 204 No Content should be returned except when the resource is modified in other ways than those specified by the request – helpermethod Feb 24 '16 at 16:34
  • 1
    @helpermethod thanks for pointing it out, seems reasonable for the standard to mandate this. It just means clients need to remember the call context, which is the right thing to do and should be easy in principle, but surprisingly not well supported in many http client libraries (web/JS or otherwise). – mahemoff Feb 24 '16 at 18:36
  • Since JSON Patch addresses list items only by their index (rather than id field), this solution will **delete the wrong row** if the list was changed on the server between the client fetching it and the client sending the PATCH request. Unfortunately the JSON Patch standard provides no way to solve this, so you have to implement a separate mechanism to ensure the list was not changed (e.g. ETag/If-Match headers). But this negates most of the benefit of using PATCH rather than PUT. – Ian Goldby Sep 15 '21 at 10:52