Most of the time, we consume APIs, not write them. And even when you do write an API, it’s almost always to modify or expand an existing API. That means following existing conventions that were put into place when the API was first written, no matter what, because maintaining consistency is important and breaking existing clients is absolutely unacceptable. The unforeseen problem is that you tend to treat the design patterns you’re familiar with as the correct ones. So when you eventually do get the opportunity to design a brand new API from the ground up, it’s important to take the time to relearn what you think you know.
That’s the position I find myself in now. By far, the API I’m the most familiar with is Smartsheet’s, since I consumed that as a mobile developer for a number of years, and designed many additions and improvements. The amount of stuff you can do with that API is staggering – it’s far more complex than many enterprise APIs out there, but it’s also really old, which means there’s been a lot of opportunities for less than ideal designs to work there way in. There’s a number of trappings from this design that I started off on my current project doing, simply assuming them to be correct, because that’s the way I’ve always done them™! It’s time to take a step back and get back to basics.
Put that PUT down!
Let’s say I want to update an existing document using a RESTful API. That document’s bound to have lots of different properties such as the name of the document, font information, owner of the document, and of course the actual text of the document. If I’m just modifying the text of the document, but leaving the rest of the properties alone, the clear solution is to
PUT only the properties I want to modify, and omit the ones I don’t want to change. Right?
PUT is intended to replace an entire object, not modify elements of it. If you’re looking to just modify a section,
PATCH is a better option. You’ll find a lot of APIs behave this way though. In part, because
wasn’t even a thing until 2010, and wasn’t a widely adopted part of the standard until later (as all new standards take time to proliferate).
But even now, a decade later, it’s still an opinionated subject. And I agree that it’s not strictly necessary to use
PATCH to apply a partial update. But then again, you could also send a large body of information along with your
GET request and have updates applied that way – as long as the server and client both agree to it, you can do whatever you want!
The reason different HTTP verbs exist is to help make intent clear. To a new viewer of your API,
PATCH much more clearly broadcasts the intent of the action – to modify part of the object, not replace it. Given the opportunity to make a choice between the two, following conventions is preferable.
There’s one time I’d argue against using
PUT. And that’s if your API is already using
PUT as the established convention. Even if you’re writing a new endpoint, if the rest of the existing API consistently follows one established format, for the sake of your users, keep using that format. The intent of your local API will be better understood if it is internally consistent, even if that goes against the format everyone else uses. After all, only nerds read formal specification docs. Your users are cooler than that, so do them the favor of not having to stop and think about every endpoint.
In summation, if you’re designing a new API from the ground up, I implore you to use
PUT when partially modifying stuff as this makes your intent more clear. But maintaining consistency is more important, as this reduces cognitive load on your users and reduces the frustration they’ll feel as they switch between endpoints.