7.5. HTTP Methods in REST
Table of Contents
Why HTTP Methods Matter in REST
In a REST API, the URL (path) identifies what you are working with, and the HTTP method tells the server what you want to do with it.
For example, these two requests mean very different things, even though they use the same URL:
GET /users/123
DELETE /users/123GET /users/123asks to read user 123.DELETE /users/123asks to delete user 123.
In REST, methods carry meaning. If you use them correctly, your API becomes predictable and easy to understand.
Key rule: In REST, you should use HTTP methods according to their standard semantics:
GETto read.POSTto create or perform a non-idempotent action.PUTto fully replace a resource.PATCHto partially update a resource.DELETEto remove a resource.
You already have separate chapters for each method, so this chapter focuses on:
- How methods map to CRUD operations.
- Important properties such as idempotency and safety.
- How to choose the right method in real API design.
CRUD and HTTP Methods
Backend systems often think in terms of CRUD:
| CRUD action | Description | Typical HTTP methods |
|---|---|---|
| Create | Add a new resource | POST, sometimes PUT |
| Read | Retrieve existing resource(s) | GET, sometimes HEAD |
| Update | Change existing resource | PUT, PATCH |
| Delete | Remove resource | DELETE |
A common REST pattern for a resource called users looks like this:
| Operation | HTTP method | URL |
|---|---|---|
| List users | GET | /users |
| Get a single user | GET | /users/{id} |
| Create a new user | POST | /users |
| Replace a user | PUT | /users/{id} |
| Partially update a user | PATCH | /users/{id} |
| Delete a user | DELETE | /users/{id} |
You will see this table repeatedly in real APIs such as GitHub, Stripe, or many internal company APIs.
Safety and Idempotency
Two important concepts help you choose the right method: safety and idempotency.
Safety
A method is safe if it is not supposed to change server state.
- Safe methods:
GET,HEAD,OPTIONS - Unsafe methods:
POST,PUT,PATCH,DELETE
Safe methods should only read data, not create, update, or delete.
Examples:
GET /postsmust not create new posts.GET /posts/10/likethat creates a like is a bad design, becauseGETis supposed to be safe. A better design isPOST /posts/10/likes.
Rule: GET must not have side effects like creating, updating, or deleting data.
Idempotency
A method is idempotent if making the same request multiple times in a row has the same effect as making it once.
Examples:
- If you call
DELETE /users/123once or 10 times, the result is the same: user 123 is gone. - If you call
PUT /users/123with the same body multiple times, the user ends up with the same data.
This does not mean the response is always the same, only that the final state of the resource does not change after the first successful call.
Common methods and idempotency:
| Method | Safe | Idempotent | Typical use |
|---|---|---|---|
GET | Yes | Yes | Read data |
HEAD | Yes | Yes | Read metadata (headers only) |
OPTIONS | Yes | Yes | Discover capabilities |
POST | No | No | Create resources, non-idempotent actions |
PUT | No | Yes | Replace a resource |
PATCH | No | Not guaranteed | Partially modify a resource |
DELETE | No | Yes | Delete a resource |
Rule: POST is not idempotent, PUT and DELETE should be idempotent, GET should be both safe and idempotent.
Why this matters:
- Idempotent methods are easier to retry safely on network failures.
- Many HTTP clients, proxies, and load balancers rely on these semantics.
Overview of Key HTTP Methods in REST
You have separate chapters for each of these, so here we will focus on how they fit together and how to choose between them.
GET
Used to retrieve data.
Examples:
GET /users
GET /users/42
GET /posts?author_id=42&page=2- Must not change server data.
- Can use caching, because it is safe and idempotent.
Common misuse:
GET /users/createthat creates a user is wrong. UsePOST /usersinstead.
POST
Used to create a resource or start an action that is not idempotent.
Examples:
POST /users
POST /orders
POST /orders/123/cancel
POST /reports/generateTypical behavior:
- When
POST /userscreates a user, the server often returns: 201 Createdstatus.- The new resource in the body.
- A
Locationheader pointing to/users/{new_id}.
POST is flexible:
- It can create child resources under a collection, such as
/users. - It can also represent actions, such as
/users/123/reset-password.
PUT
Used to fully replace a resource at a known URL.
Examples:
PUT /users/123
PUT /settings/global
In PUT /users/123, the body contains the entire representation of the user, not just the fields you want to change.
Key properties:
- Idempotent: sending the same full user data again does not change the state after the first request.
- Can be used to create a resource if the client already knows the ID and the server allows it.
Example: client chooses the ID:
PUT /users/alice
Content-Type: application/json
{
"id": "alice",
"name": "Alice Smith",
"email": "alice@example.com"
}
If /users/alice does not exist, the server may create it. If it exists, the server replaces its data.
PATCH
Used to partially update an existing resource.
Examples:
PATCH /users/123
Content-Type: application/json
{
"email": "new-email@example.com"
}- Typically used when you want to update only 1 or 2 fields.
- Often not idempotent by default, but you can design it to be idempotent if each patch is a deterministic description of the final state.
Comparison:
PUT /users/123expects the full user data.PATCH /users/123expects only the fields that change.
DELETE
Used to remove a resource.
Examples:
DELETE /users/123
DELETE /posts/99/comments/5- Idempotent: after the first successful deletion, further
DELETEcalls should not change the server state. - The server can return
204 No Contentto indicate success without a body.
Designing REST APIs with Methods
Picking the correct method for each endpoint is part of designing a RESTful API.
Common Resource Patterns
Imagine you design an API for a simple blogging system with:
- Users
- Posts
- Comments
Users
| Action | Method | URL | Notes |
|---|---|---|---|
| List users | GET | /users | Optional filters as query params |
| Create user | POST | /users | Body contains user data |
| Get single user | GET | /users/{id} | |
| Replace user | PUT | /users/{id} | Full user body |
| Partially update user | PATCH | /users/{id} | Only changed fields |
| Delete user | DELETE | /users/{id} |
Posts
| Action | Method | URL |
|---|---|---|
| List posts | GET | /posts |
| Create post | POST | /posts |
| Get single post | GET | /posts/{id} |
| Update post fully | PUT | /posts/{id} |
| Update post partially | PATCH | /posts/{id} |
| Delete post | DELETE | /posts/{id} |
| List comments of a post | GET | /posts/{id}/comments |
| Add comment to a post | POST | /posts/{id}/comments |
Custom actions
Sometimes you need an action that does not fit simple CRUD, for example liking a post.
Bad design:
GET /posts/123/likethat likes the post.
Better designs:
- Treat likes as a resource:
POST /posts/123/likesto like.DELETE /posts/123/likesto unlike (if user is implied from auth).- Or use an action endpoint with
POST: POST /posts/123/likePOST /posts/123/unlike
Both approaches use methods in a way that respects their semantics: an action that changes state should not be GET.
Choosing Between POST, PUT, and PATCH
These three methods are often confusing. Here are some practical guidelines.
When to Use POST
Use POST when:
- The server generates the resource ID.
- You are adding something to a collection.
Examples:
POST /users # Server decides user id
POST /orders # Server decides order id
POST /posts/123/comments # Server decides comment id
Also use POST for:
- Actions that do not simply fit CRUD.
Examples:
POST /auth/login
POST /payments/123/refund
POST /reports/generateWhen to Use PUT
Use PUT when:
- The client knows the resource URL.
- You are replacing the entire resource representation.
Examples:
PUT /users/123
PUT /profiles/john-doe
PUT /settings/globalDecide on a rule:
- Either you allow
PUTto also create if the resource does not exist. - Or you require the resource to exist and return
404 Not Foundif it does not.
Be consistent in your API.
When to Use PATCH
Use PATCH when:
- You want to update only some fields.
- The client does not want to send the full resource.
Examples:
PATCH /users/123
{
"name": "New Name"
}
PATCH /users/123
{
"is_active": false
}You will define how the server interprets the payload. A common rule is:
- Only the fields present in the request body are modified.
- Other fields keep their previous values.
Idempotency in Real Scenarios
Idempotency is very important for retries. For example, a client might send a request, get a timeout, and try again. If the method is idempotent, this is safer.
Idempotent Example: PUT
Imagine you have:
PUT /accounts/123/balance
Content-Type: application/json
{ "balance": 1000 }Whether this is called once or five times, the final balance is 1000.
Non Idempotent Example: POST
Imagine:
POST /orders
Content-Type: application/json
{ "item_id": 42, "quantity": 1 }
If this is called twice because of a timeout, the user might receive two orders. This is correct behavior, because POST is non idempotent.
To protect from this in real systems, APIs sometimes use:
- Idempotency keys in headers, to ensure a repeated
POSTwith the same key does not create multiple resources. - This is an advanced topic, but it shows why understanding method semantics matters.
Common Design Mistakes and How to Avoid Them
Misusing GET for state changes
Bad:
GET /users/123/activate
This changes the user from inactive to active, which violates the safety of GET.
Better:
POST /users/123/activateor a more RESTful resource-oriented design:
POST /users/123/activation # create an activation
DELETE /users/123/activation # remove activation (deactivate)Using POST for everything
Some APIs use only POST and GET, for example:
POST /updateUser
POST /deleteUser
POST /getUserThis might work, but the API:
- Ignores HTTP semantics.
- Is harder to understand for other developers.
- Does not play well with caches and standard tools.
Instead, use:
GET /users/123
PUT /users/123
DELETE /users/123Confusing PUT and PATCH
If you design PUT /users/123 to accept partial updates, then you blur the line:
- Clients cannot be sure if missing fields are left untouched or cleared.
- It becomes unclear why
PATCHexists.
Better:
- Decide that
PUTalways expects a full representation. - Decide that
PATCHis for partial, minimal updates.
Practical Examples
Here are some complete request and response examples to see methods in context.
Creating a resource with POST
POST /users
Content-Type: application/json
{
"name": "Alice",
"email": "alice@example.com"
}Possible response:
HTTP/1.1 201 Created
Location: /users/123
Content-Type: application/json
{
"id": 123,
"name": "Alice",
"email": "alice@example.com",
"created_at": "2026-08-27T10:00:00Z"
}Reading the created resource with GET
GET /users/123
Accept: application/jsonResponse:
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": 123,
"name": "Alice",
"email": "alice@example.com",
"created_at": "2026-08-27T10:00:00Z"
}Fully replacing the user with PUT
PUT /users/123
Content-Type: application/json
{
"id": 123,
"name": "Alice Smith",
"email": "alice.smith@example.com"
}This request overwrites the user. Any fields not sent might be set to default or removed, depending on your API design.
Partially updating the user with PATCH
PATCH /users/123
Content-Type: application/json
{
"name": "Alice Johnson"
}
Only the name changes. Other fields remain unchanged.
Deleting the user with DELETE
DELETE /users/123Response:
HTTP/1.1 204 No Content
If the client sends DELETE /users/123 again, the server may return:
HTTP/1.1 404 Not FoundThe state of the system is still the same as after the first delete, so the method remains idempotent.
Summary
- REST uses HTTP methods to express what action you want to perform on a resource.
- Key methods:
GETfor reading, safe and idempotent.POSTfor creating and non idempotent actions.PUTfor full replacement, idempotent.PATCHfor partial updates.DELETEfor deletions, idempotent.- Safety and idempotency are important properties that influence:
- How clients can retry requests.
- How intermediaries like caches and proxies behave.
- Good REST design uses the methods according to their standard meaning, which makes your API more intuitive and robust.
In the following chapters, you will dive into each method in detail and see how to implement and use them in real backend code.
Views: 9
KAHIBARO