Choosing the Best Approach for Partial Updates in REST API

Whenever I design the REST API, I take a look at how other people have designed their APIs. There are a couple of benefits to this approach. Firstly, I get some ideas of the typical problems I may encounter, which saves me from reinventing the wheel. However, perhaps what’s even more important is that I gain an insight into whether a common approach is typically used to design a given API feature.

Recently I had to add partial updates feature to REST API I was working on. I also checked how other APIs implement it. It seems there is no consensus on the best approach in this case. Below approaches I found and my thoughts about them.

Why partial updates anyway?

Imagine we have a user entity with dozens of different properties and we want to update only single property, let’s say status, knowing only user ID. As a workaround, we could pull complete user record first, update its status and then send it back. However, it adds unnecessary request making system a bit slower.

1. PUT request with partial object

In this approach request sent to the same API endpoint as for full update. However, API does not change any property, missing in request.

PUT /api/users/42

{status: 5}
  • easy to build request object in JavaScript and consume in API
  • not instantly clear for API consumer how missing fields will be handled (skipped or set to default values)
  • more code on API side to check if every property was sent in request or not

Who uses: Asana

2. PATCH request with partial object

This approach is similar to previous once, except it uses a different verb (hence different API endpoint), rather than reusing the one for full updates.

PATCH /users/42

{status: 5}
  • seems that it is the most common approach
  • easy to build object on a client and consume on the server
  • some will consider you an idiot

Who uses: OData

3. PUT request to sub resource

In this case, every updatable property exposed as individual endpoint. Good approach if you need to update most of properties in this manner.

PUT /api/users/42/status

5
  • simple, clear requests
  • explosion of endpoints on API side. You will likely need to use some code generation and documentation generation tool to tame them
  • can’t do atomic and transactional updates for multiple properties at once

Who uses: Trello

4. JavaScript Object Notation (JSON) Patch

HTTP specification itself does not enforce any rules on how PATCH request body should be formatted. There is a new standard emerged, called JSON Patch to fill this gap. It defines not only how properties of the resource can be updated, but also copied, moved, deleted, added and tested. It is probably an overkill for CRUDish APIs, but might be a good choice for complex APIs.

PATCH /api/users/42

[
  { "op": "replace", "path": "/status", "value": 5 }
]
  • as it is standard, theoretically it will be more common approach in a future
  • tedious to build changes description object on the client and then consume it on API side
  • most of operations declared in standard (add, remove, copy, move, test) are likely not needed in most of cases

Who uses: could not find anyone

5. Custom endpoints

Another way to handle partial updates is to create custom endpoints only for a few cases when specific properties have to be updated.

POST /api/users/42/actions/deactivate
  • easy to implement and consume
  • clear what endpoint does
  • not scalable when multiple properties for multiple objects have to be updated this way
  • can’t do atomic and transactional updated for multiple properties at once

 

  • Jorn Wildt

    A few more thoughts on partial updates on http://soabits.blogspot.dk/2013/01/http-put-patch-or-post-partial-updates.html. We do partial updates with JSON Patch (idea #4).

  • Juan Ignacio Vimberg

    Hi Alexander,

    Any thoughts on how to expose which properties of the resource are updatable and which aren’t? I can see options 3 and 5 can limit the number of possible updates, but I wonder how the other approaches would handle it.

  • http://www.apuchkov.com Alexander Puchkov

    Hi Juan,

    Update endpoints define a model they expect to be submitted to them. If some properties should never be updated then just don’t include them in a model.