HTTP Methods
Objectives
By the end of this chapter, you should be able to:
- Explain what each of
GET,POST,PUT,PATCH, andDELETEis for - Explain the difference between
PUT(full replace) andPATCH(partial update) - Explain what “idempotent” means and which methods have that property
💡 Why this matters: Last lesson covered how a REST URL identifies a resource. This lesson covers the other half: the HTTP method that says what to actually do with it. Getting the method right (not just the URL) is how a real API knows what you’re asking for.
⚠️ A note on verification: the same limitation as last lesson applies.
GETrequests against JSONPlaceholder were verified live for this course.POST,PUT,PATCH, andDELETEcan’t be executed from this sandbox (this course’s fetch calls against real APIs have used this same disclosure since Module 3), the behavior described below matches JSONPlaceholder’s own documented behavior exactly, run it yourself in a browser or Node to see it firsthand.
GET: Read a Resource
Already familiar from Module 3, GET is the default for a plain fetch(url) call, and it’s the only method with no body.
const response = await fetch("https://jsonplaceholder.typicode.com/posts/1");
const post = await response.json();
console.log(post.title);
// sunt aut facere repellat provident occaecati excepturi optio reprehenderit
POST: Create a New Resource
Also familiar from Module 3. POST sends a body and asks the server to create something new from it.
const response = await fetch("https://jsonplaceholder.typicode.com/posts", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ title: "My Post", body: "Hello", userId: 1 }),
});
const created = await response.json();
console.log(created);
// { title: "My Post", body: "Hello", userId: 1, id: 101 }
console.log(response.status);
// 201
201 Created (last lesson) is the standard success status specifically for POST, distinct from the plain 200 a successful GET returns.
PUT: Replace a Resource Completely
PUT updates an existing resource, but it’s a full replacement: whatever body you send becomes the entire resource, any field you don’t include is gone.
const response = await fetch("https://jsonplaceholder.typicode.com/posts/1", {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ id: 1, title: "Updated Title", body: "New body", userId: 1 }),
});
const updated = await response.json();
console.log(updated);
// { id: 1, title: "Updated Title", body: "New body", userId: 1 }
If the original post had additional fields and this PUT request’s body left one out, that field would be gone from the result, PUT doesn’t merge, it replaces. This is why a PUT request should always send the complete resource, not just the parts that changed.
PATCH: Update Part of a Resource
PATCH is PUT’s more surgical sibling: send only the fields that changed, everything else stays as it was.
const response = await fetch("https://jsonplaceholder.typicode.com/posts/1", {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ title: "Just the Title Changed" }),
});
const patched = await response.json();
console.log(patched);
// { id: 1, title: "Just the Title Changed", body: "quia et suscipit...", userId: 1 }
Notice body and userId in the result are untouched, the original values, even though this request’s body only mentioned title. That’s the entire distinction between PUT and PATCH: PUT says “here’s the whole thing now,” PATCH says “here’s what changed.”
DELETE: Remove a Resource
const response = await fetch("https://jsonplaceholder.typicode.com/posts/1", {
method: "DELETE",
});
console.log(response.status);
// 200
DELETE typically has no body, the URL alone identifies what to remove. A real API commonly responds with 200 and an empty object, or 204 No Content (last lesson) with no body at all, either is normal, check the specific API’s documentation for which it uses.
Idempotency: Doing It Twice Should Be Safe
A method is idempotent if making the exact same request multiple times has the same effect as making it once. This matters for handling network failures: if a request might have failed to reach the server, is it safe to just retry it?
GETis idempotent. Reading the same resource twice doesn’t change anything.PUTis idempotent. Sending the same full replacement twice results in the same final state either way.DELETEis idempotent. Deleting the same resource twice, the second time, it’s already gone, still ends with it gone.POSTis not idempotent. Sending the same “create a new post” request twice creates two posts, not one.PATCHis usually not idempotent, though it depends on what’s being patched.{ "views": 5 }(set views to exactly 5) is idempotent.{ "views": "increment" }(add one to whatever it currently is) is not, running it twice gives a different result than running it once.
This is why safely retrying a failed request is straightforward for GET, PUT, and DELETE, but risky for POST, a retry might mean “I asked for this to happen twice.”
Try It
- Given
PUT /users/5with a body of{ name: "Jordan" }(missing every other field a user normally has), explain what you’d expect to happen to those missing fields, based on howPUTbehaves. - Rewrite that same request as a
PATCHinstead, and explain how the outcome would differ. - List the five methods from this lesson and mark each as idempotent or not, with a one-sentence reason for each.
- Write the
fetch()call for aPATCHrequest tohttps://jsonplaceholder.typicode.com/posts/1that only changes thetitleto"Practice Patch".
Recap
GETreads,POSTcreates,PUTfully replaces,PATCHpartially updates,DELETEremoves.PUTrequires the complete resource in itsbody, missing fields are lost.PATCHonly needs the fields that changed, everything else stays as it was.- A method is idempotent if repeating it has the same effect as doing it once.
GET,PUT, andDELETEare,POSTisn’t,PATCHdepends on what’s being patched. - Idempotency is what makes it safe to blindly retry a failed request for some methods, and risky for others.
Next lesson: sending authentication with a request, so an API knows who’s asking.