Skip to content

Proposal: Use a combination of test and remove JSON Patch operations instead of treating to-many relationships like sets #176

@fancyremarker

Description

@fancyremarker

Issue #100 (and the discussion on #99 also) reveal an unresolved question in the spec, around how to properly form JSON Patch operations that remove an item from a to-many relationship. Currently, the spec says:

While to-many relationships are represented as a JSON array in a GET response, they are updated as if they were a set. [...] To remove an element from a to-many relationship, use a remove operation on links/<name>/<id>.

This is problematic because JSON Pointer (RFC 6901), the address format for JSON Patch's (RFC 6902) path, makes no mention of sets, only arrays. Consider the following example resource, a post with 4 comments:

{
  "posts": [{
    "id": "1",
    "links": {
      "comments": [ "1", "3", "5", "7" ]
    }
  }]
}

The current JSON API spec says that if we want to remove the comment with ID 3, we'd make the following PATCH request:

PATCH /photos/1

[
  { "op": "remove", "path": "/posts/0/links/comments/3" }
]

This is a valid JSON Patch document, but its standard semantics are different from what the JSON API spec would have it mean. A naive client built on a compliant JSON Patch library could very easily make the above request with the intention of removing the element with index 3 in the comments array (i.e., comment 7), but instead, our JSON API-compliant server would remove the wrong comment, comment 3.

I propose that in order to remove an element from a to-many relationship, a client must use a remove operation on links/<name>/<arrayIndex>, along with a test that links/<name>/<arrayIndex> has the value we expect. With our example from above, this would look like:

PATCH /photos/1

[
  { "op": "test", "path": "/posts/0/links/comments/1", "value": "3" }
  { "op": "remove", "path": "/posts/0/links/comments/1" }
]

This is guaranteed to always be safe, and also complies with both the JSON Patch and JSON Pointer specs. For more info on the test operation see RFC 6902, §4.6.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      pFad - Phonifier reborn

      Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

      Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


      Alternative Proxies:

      Alternative Proxy

      pFad Proxy

      pFad v3 Proxy

      pFad v4 Proxy