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.