skip to Main Content

Let’s assume you have an API endpoint that returns user data with expanded country data:

GET user/1

{
    UserName: "John Miller",
    Country: {
        Id: 1,
        Name: "Switzerland"
    }
}

Now you can also modify user data with the same endpoint. What I want to do is change the relation of the user and the country, not the country itself.
I see two possibilities for the structure to do this.

PATCH user/1

{
    UserName: "John Miller",
    Country: {
        Id: 2
    }
}

PATCH user/2

{
    UserName: "John Miller",
    CountryId: 2
}

The first version will keep the structure, but only require the id. The second one will not be nested and directly contain the id.

Is there any best practise or guideline how to do this?

2

Answers


  1. Chosen as BEST ANSWER

    I think the question was not clear enough. Basically I wanted to know how to control the relation between user and country with a correct json format. Since the CountryId is also stored on the user table itself I think the following structure makes most sense for my case:

    Reading data:

    {
        UserName: "John Miller",
        Country: {
            Id: 1,
            Name: "Switzerland"
        }
    }
    

    The country data is expanded here, because I need detailed information about the country of the user.

    Saving data:

    {
        UserName: "John Miller",
        CountryId: 2
    }
    

    Because I want to change the relation of the user and country, and I do not want to change the country itself, the CountryId is set on the user level. It is also reflecting the foreign key in the database. It would only make sense to use the expanded country, if I wanted to modify the country "Switzerland" itself while also making changes to the user in one transaction. So the following example would also make sense:

    PATCH user/1

    {
        UserName: "John Meyer",
        Country: {
            Id: 1,
            Name: "New Switzerland"
        }
    }
    

  2. What REST does is concentrate that need for prior knowledge into readily standardizable forms. — Fielding, 2008

    In other words, part of the point of REST is to do things the same way that everybody else does them, so that general purpose tooling works.


    If you are sending an HTTP PATCH request to modify the representation of a resource on a web server, then you should strive to use a standardized representation of the set of changes.

    For JSON documents, two standardized forms are

    • JSON Patch/json-patch+json, as described by RFC 6902
    • JSON Merge Patch/merge-patch+json, as described by RFC 7396

    json-patch+json really does look like a set of changes; these patch documents are lists of operations that describe each individual change that you want to make

    [
      { "op": "replace", "path": "/a/b/c", "value": 42 },
      { "op": "test", "path": "/a/b/c", "value": "C" }
    ]
    

    Merge patch looks much closer to what you are already trying to do; the document is, in effect, a stripped down version of the original representation, with a standardized set of rules describing the semantics of the differences in the documents.

    {
      "a":"z",
      "c": {
        "f": null
      }
    }
    

    Commonly, for resources where PATCH semantics make sense, PUT semantics also make sense for similar reasons — so your API should probably offer both, and allow the client to choose which method to use to share its changes.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search