Last week, there was a trending hot take on social media: why bother with HTTP methods beyond GET
and POST
in your API? The argument was that URLs are cheap, so why not create more API URLs rather than using the same URL with different HTTP methods? It was a very interesting thought process around API design because it is the opposite of my thinking. I am a fan of RESTful semantic APIs and using HTTP methods to adequately describe the action an endpoint is performing on a resource. I am also an API design nerd, hence this blog post.
Generally, HTTP methods represent the following actions:
GET
retrieves data.POST
creates data.PUT
updates data entirely.PATCH
allows partially updating data.DELETE
removes data.
PATCH
was introduced as a new HTTP method in RFC 5789: PATCH Method for HTTP. I have not come across an API implementing both PUT
and PATCH
. Generally the API uses one or the other. PUT
requires updating all data properties, whereas PATCH
allows updating only specific properties. If you haven't done a deep dive into HTTP methods, I recommend reading the MDN documentation or RFC 9110: HTTP Semantics.
The example that piqued my interest involved an API for reservations. Let's model an API for a reservation resource using each HTTP method. Then, we'll review what it'd look like only using GET
and POST
.
The API has two paths for accessing reservation resources: /reservations
and /reservations/{id}
.
GET /reservations
retrieves all reservations for the user.GET /reservations/{id}
retrieves a user's specific reservation.POST /reservations
creates a new reservation for the user.PATCH /reservations/{id}
to change the time or number of people for the user's reservation.DELETE /reservations/{id}
to remove a user's reservation.
While I would defer to using PATCH
so that the time number of people can be modified individually, the API could require PUT
instead. Changing either value could be interpreted as replacing the reservation, essentially replacing the reservation resource without changing its identifier.
Now, let's envision this API using only GET and POST methods
GET /reservations
retrieves all reservations for the user.GET /reservations/{id}
retrieves a user's specific reservation.POST /reservations
creates a new reservation for the user.POST /reservations/{id}/change
to change the time or number of people for the user's reservation.POST /reservations/{id}/cancel
to remove a user's reservation
The API is mostly the same until we reach the endpoints that modify or delete the reservation. Now we have a /reservations/{id}/change
and /reservations/{id}/cancel
paths. Not that big of a change. The API client needs to use a few different paths versus HTTP methods.
However, let's remember what API stands for application programming interface. The emphasis is on "interface." An API is an interface between two different systems. Interfaces are intended to be contracts to encapsulate logic so that the two systems can be decoupled. My concern about the latter approach with paths such as /reservations/{id}/change
and /reservations/{id}/cancel
is that they are specific. You may think I'm splitting hairs, but we must assume the software we write will outlast us and the original requirements.
An argument I read against DELETE /reservations/{id}
in favor of POST /reservations/{id}/cancel
was the internal state of the reservation resource. Does deleting a reservation delete the resource permanently? Or is it marked as canceled and still accessible in the list of reservations? If the reservation is canceled, is it really deleted? This exact discussion is why I prefer using HTTP methods in my APIs.
What if the behavior wasn't explicitly outlined in the architecture or user stories? Matching API resource endpoint operations against HTTP methods brings up discussions when they're not entirely aligned. To me, anything that performs a hard or soft delete still applies to the DELETE
method. That is logic specific to the backend and encapsulated.
In this example I would add DELETE /reservations
, which allows deleting canceled reservations in bulk. This
URLs may be cheap. But they come at a design cost when building your API.
I'm available for one-on-one consulting calls – click here to book a meeting with me 🗓️
Want more? Sign up for my weekly newsletter