Replacing and Changing a Note
Note 42 has the title “Groceries”. The person wants the title to be “Groceries for Friday” and wants to keep the body. Two requests can do this. They differ in how much the client sends.
Replacing a note
PUT replaces the whole note with what the client sends:
PUT /notes/42 HTTP/1.1
Host: api.notes.example
Content-Type: application/json
{
"title": "Groceries for Friday",
"body": "Milk, eggs, bread"
}
The path names the note being replaced. The body is what the note should be after the request. The response is 200 OK with the whole note, and its updated_at has a new value.
A PUT has to include both fields. Suppose a client sends only a title. The server cannot tell whether the client wants the old body kept or cleared. Instead of guessing, the server refuses the request with 400 Bad Request. A PUT to a note that does not exist gets 404 Not Found.
Upsert with PUT
In some APIs a PUT can create a resource that is missing. The client sends the whole representation, and the server creates it with that representation. This is called upsert, a blend of update and insert. The term is borrowed from the SQL language.
I prefer to restrict PUT to only replace existing resources. The client has to create the note with POST first, and then it can replace it with PUT.
Changing part of a note
PATCH changes only the fields the client sends:
PATCH /notes/42 HTTP/1.1
Host: api.notes.example
Content-Type: application/merge-patch+json
{
"title": "Groceries for Friday"
}
The response is again 200 OK with the whole note. It has the new title and a new updated_at.
The Content-Type here is different. It names a format called JSON Merge Patch, which tells the server how to read the body. In that format, a field that is in the body changes, and a field that is left out keeps its value. Since the title is present, it changes. The body is missing, so it keeps its value.
Sending null for a field means removing it. If the field is required, the server refuses the request with a 400 error. As with PUT, a PATCH to a note that does not exist gets 404.
Choosing between them
A client with an editing screen that shows both fields has the whole note and can send a PUT. A client with a rename button knows only the title, so it sends a PATCH. The API offers both because its clients differ. If no client ever needed to replace a whole note, the API could offer only PATCH.