To PATCH Or PUT?

Not applicable

I'm redesigning a fairly large API. We're considering supporting the PATCH verb.

It appears like there are 2 basic standards we might choose from. JSON Patch:
https://tools.ietf.org/html/rfc6902

Or JSON Merge Patch:
https://tools.ietf.org/html/rfc7396


JSON Patch is more flexible / descriptive but I don't think I would want to program against that spec as a client. If I'm writing a simple JavaScript client I wouldn't want to generate the payloads necessary in the JSON Patch spec.

JSON Merge Patch is much simpler / easier to understand but i doesn't handle partially updating nested arrays - you need to send the entire nested array and perform a merge which can get a little complicated.

Does anyone out there have practical experience with PATCH? Is it worth implementing or is it better to just support partial models in the PUT?

Solved Solved
1 5 1,555
1 ACCEPTED SOLUTION

How complex are the entities? I'm a fan of full replacement via PUT because then you don't need to worry about how to remove elements. If that's not OK then I think I'd lean towards partial models with put. That first spec seems ok, but I think I'd only use it for narrow use cases. It just doesn't seem very developer friendly, so unless you really need something like that I think I'd avoid it. Just my 2 cents.

View solution in original post

5 REPLIES 5

How complex are the entities? I'm a fan of full replacement via PUT because then you don't need to worry about how to remove elements. If that's not OK then I think I'd lean towards partial models with put. That first spec seems ok, but I think I'd only use it for narrow use cases. It just doesn't seem very developer friendly, so unless you really need something like that I think I'd avoid it. Just my 2 cents.

Thanks for the help @Carlos Eberhardt and @Sean Davis

It's good to know what other people are doing. We're considering PUT with partial models but that seems to go against the specification for PUT. Or only supporting PATCH but making it idempotent - that's a long conversation but it's possible.

My 2cents - i like the idempotency of PUT. I also see PUT much more commonly.

Not applicable

Per @sarthak's request I'm posting a followup I sent to him privately.

I’m kind of surprised there is not more momentum in the industry towards PATCH. We’ve had several conversations around PUT vs PATCH.

The first basic question was this – how will we handle missing fields in a PUT.

These kinds of fields are nullable in our database (like a Patient’s middle name)

Possible actions for missing optional/nullable fields in a PUT could be:

1.We set the field to null.

2.We throw an exception.

3.We ignore the field – retain whatever the current value is in the database.

Option 1 seems dangerous. Some of our data models (like Patient) can have well over 100 fields (unfortunately the core product actually displays a huge amount of data and this is unavoidable). If an API consumer accidentally writes bad code that forgets to include a field in a PUT, we would accidentally clear a lot of data. It could take days or weeks before we realize we were clearing data accidentally. The data is very hard or impossible to recover. It would only take 1 bad application to accidentally delete a lot of data in production.

Option 2 is safe. It’s also too verbose and requires clients to send a lot of data that isn’t usually necessary. We want to make sure we can target mobile apps that don’t want to stream large data sets if they don’t have to. If the mobile app is only exposing 10 of these fields it doesn’t make sense to require them to send the entire patient data model. Especially on mobile apps with limited bandwidth.

For myself, option 3 is the safest / most preferable. If we went with option 3, it makes less sense to expose the PATCH http verb. But it seems like we’re breaking the PUT specification.

https://tools.ietf.org/html/rfc7231#page-26

According to the PUT spec, PUT and GET should be fairly transitive – the input to PUT should match closely to what we receive from a subsequent GET. Meaning, option 3 should be avoided. Calling PUT with a single field and then calling GET but returning 100 fields doesn’t seem correct if we follow the spec.

If we wanted to follow the PUT spec, I think we would go with option 2. But partial updates are important to us for mobile. Therefore we would need to implement PATCH. But if we support PATCH, we don’t need PUT anymore because PATCH can be used for full updates as well. Some argue that we need PUT because PATCH isn’t idempotent – meaning if we call PATCH many times that the state of our system is the same as the first invocation. We could actually make our implementation of PATCH idempotent pretty easily but that’s a longer conversation.


We’re considering

1.Support PATCH but not PUT

2.Ignoring the PUT specifications and support option 3 – ignore missing fields. In this case we don't need PATCH

From the posts from you and the responses on the community thread, it appears like most people are going with supporting PUT with missing fields. Is that fairly accurate?

After discussion with my team this morning,,, we're concerned with adopting PATCH if there isn't momentum / more wide spread adoption of it.

I would go with PUT if client is able to provide all other properties of the entity in the request, i.e. all properties in the request are related to the one that is changed so they all can go in the same request. For a news api, modifications on summary, title, descriptions, ...etc properties.

If the client doesn't necessarily know about all other properties when change is happening, e.g. modification of the news article category/label - client shouldn't need to resend the summary, description, content, etc if category is changing. It is possible that the UI area where you modify article description, summary, content is different from the one you make category assignments. So UI as the client shouldn't have to carry the entire news object around just to change the category. I would go with PATCH for this usecase with id and category/label as the input.

Specifically for arrays, I would ask the client to use either PUT or PATCH (subject to above comments to choose which one) but provide the entire array. Client should already have the entire array if it is modified so should be able to send it off to the server in its entirety. Dealing with merges, diff of arrays to understand which one is modified/deleted is a complexity which you may not need to implement.