Http Verbs
HTTP verbs provide the action counterpart to the noun-based resource. Let's find out the primary or most commonly used verbs.
HTTP verbs provide the action counterpart to the noun-based resource. The primary or most commonly used verbs are as follows:
CRUD Operations
Verb | CRUD | Collection1 | Item2 | Idempotent | Responses |
---|---|---|---|---|---|
POST | Create | ✔ | 201 (Created), Location header with link to /orders/{id} containing new id.409 (Conflict) if resource already exists. 202 (Accepted) for batch processing. | ||
GET | Read | ✔ | ✔ | ✔ | 200 (Ok), returns list of orders or single order. 404 (Not Found), if id is invalid or not found. 400 (Bad Request), if a query parameter is invalid. |
PUT | Update/Replace | ✔ | ✔ | 200 (Ok) or 204 (No Content) 404 (Not Found) | |
PATCH | Update/Modify | ✔ | ⁇ | Same as PUT | |
DELETE | Delete | ✔ | ✔ | 200 (Ok) 404 (Not Found) |
Responses
Status Code | Description |
---|---|
200 OK | The request was successful. |
201 Created | The resource was successfully created. |
202 Accepted | The request has been accepted for processing. |
204 No Content | The request was successful but there is no content to return. |
400 Bad Request | The request could not be understood or was missing required parameters. |
401 Unauthorized | Authentication failed or user does not have permissions for the desired action. |
403 Forbidden | Authentication succeeded but authenticated user does not have access to the resource. |
404 Not Found | The requested resource could not be found. |
409 Conflict | Request could not be processed because of conflict. |
500 Internal Server Error | An error occurred on the server. |
POST
The POST method is used to create resources. Creating a resource is one of the actions that change the state of an application, so caution should be taken when performing this action multiple times. If two identical POST requests are made, it is likely that two resources containing the same data will be created. This is described as being non-idempotent. Therefore, use the POST verb only for resource requests that do not require idempotency.
If idempotency is required, use PUT. In this case, idempotency is ensured by updating the resource if the client provides a resource ID, or creating a new resource if not.
On the other hand, POST is used to trigger endpoints that act like functions. Endpoints that may take a long time to complete should immediately return a 202 (Accepted) and provide a link to check the status of the process while it completes. The client can periodically call this link to check the completion of the task and inform the user.
This exceptional use of the POST method allows for exceptions in endpoint naming. Both nouns and verbs can be used together, formatted like function names as follows:
- POST /saving-accounts/calculate-interest
- POST /members/import-data
POST on a Collection or Item Endpoint?
The POST method is used to create a new resource at a collection endpoint. For instance, to create a new user, you can send a POST request to the /users
endpoint.
POST /users
{
"name": "John Doe",
"email": "johndoe@example.com"
}
This request creates a new user, and the server responds with the ID of the newly created user.
Response:
201 Created
Location: /users/123
{
"id": 123,
"name": "John Doe",
"email": "johndoe@example.com"
}
In this example, the POST method is used to add a new user to the /users collection.
Why POST is Not Used for Item Endpoints
Item endpoints already include an ID that identifies a specific resource. Therefore, a POST request is not appropriate. For example, if the user data already exists at /users/123
, the following POST request would be incorrect:
POST /users/123
{
"name": "Jane Doe",
"email": "janedoe@example.com"
}
This request doesn't make sense because POST is used to create new resources, and trying to create a new resource at an existing resource's endpoint is illogical. Instead, you should use the PUT or PATCH methods to update an existing resource.
GET
The GET method is used to retrieve a representation of a resource. This is idempotent which means calling it once has the same effect as calling it 10 times. This should never modify any resources on the server. GET verbs can retrieve both a collection or a single item. For the collection of items, use pagination, sorting, and filtering to navigate through big lists.
Why GET Can Be Used for Both Collection and Item Endpoints
The GET method can be used for both collection and item endpoints because its primary purpose is to fetch data, whether it's a list of resources or a specific resource.
GET on a Collection Endpoint
When you use GET on a collection endpoint, it retrieves a list of resources. For example, to get a list of users, you would send a GET request to the /users
endpoint.
GET /users
This request retrieves all users, and the server responds with a list of user objects.
Response:
200 OK
[
{
"id": 1,
"name": "John Doe",
"email": "johndoe@example.com"
},
{
"id": 2,
"name": "Jane Doe",
"email": "janedoe@example.com"
}
]
In this example, the GET method is used to fetch all users in the /users collection.
GET on an Item Endpoint
When you use GET on an item endpoint, it retrieves a specific resource identified by its ID. For example, to get a specific user with the ID 123, you would send a GET request to the /users/123
endpoint.
GET /users/123
This request retrieves the user with the ID 123, and the server responds with the user object.
Response:
200 OK
{
"id": 123,
"name": "John Doe",
"email": "johndoe@example.com"
}
In this example, the GET method is used to fetch a single user from the /users
collection.
The GET method is versatile and can be used to retrieve both collections and individual items. It is idempotent and does not alter the state of resources on the server, making it suitable for read-only operations.
PUT
The PUT method is most often utilized for UPDATE capabilities. This replaces the whole object while PATCH partially replaces the object. However, PUT can also be used to create a resource when the resource id is chosen by the client instead of by the server. As the client send an id, the server can create or update a resource depending on its existence, a.k.a. UPSERT.
On a successful update, return a 200 (or a 204 if returning no content in the body) from a PUT. If you are using PUT to create, return HTTP status of 201 on its successful creation. A body in the response is optional; remember that providing one consumes more bandwidth. Returning a link via a Location header during its creation is not necessary since the client already sets the resource ID. It is recommended to keep PUT requests idempotent, and use POST for non-idempotent requests.
Why PUT Can Be Used for Both Creating and Updating Resources
The PUT sends a complete representation of a resource to the server. If the resource exists, it is updated; if it does not exist, it can be created.
PUT on an Item Endpoint
When you use PUT on an item endpoint, it updates the resource identified by its ID. For example, to update the user with ID 123, you would send a PUT request to the /users/123
endpoint.
PUT /users/123
{
"name": "Jane Doe",
"email": "janedoe@example.com"
}
This request updates the user with ID 123, and the server responds with a status indicating the outcome.
Response:
200 OK
{
"id": 123,
"name": "Jane Doe",
"email": "janedoe@example.com"
}
PUT for Creating a Resource
If the resource does not exist and the client provides the resource ID, the PUT method can be used to create the resource. For example, if there is no user with ID 123, the same PUT request would create a new user with that ID.
PUT /users/123
{
"name": "Jane Doe",
"email": "janedoe@example.com"
}
Response:
201 Created
{
"id": 123,
"name": "Jane Doe",
"email": "janedoe@example.com"
}
PUT is idempotent and requires a complete representation of the resource. When used on an item endpoint, it can either update the existing resource or create a new one if it does not exist. PUT should not be used on collection endpoints as it operates on individual resources identified by their IDs.
PATCH
The PATCH method is used for modify capabilities. The request only contains the changes to the resource, and not the complete resource. It is neither safe nor idempotent according to the HTTP specifications. If the outcome should be idempotent, use PUT with a whole object.
PUT / PATCH are the action to an item. If a request is made to a collection URI (without an id), return 405 (Method Not Allowed), unless you want to update every resource in the entire collection.
Why PATCH is Used for Partial Updates
The PATCH method is designed for situations where you need to update only certain fields of a resource without modifying the entire resource. This makes PATCH more efficient than PUT when only partial updates are needed.
PATCH on an Item Endpoint
When you use PATCH on an item endpoint, it applies partial modifications to the resource identified by its ID. For example, to update only the email of the user with ID 123, you would send a PATCH request to the /users/123
endpoint.
PATCH /users/123
{
"email": "newemail@example.com"
}
This request updates the email field of the user with ID 123, and the server responds with a status indicating the outcome.
Response:
200 OK
{
"id": 123,
"name": "John Doe",
"email": "newemail@example.com"
}
When to Use PATCH
Use the PATCH method when you need to make partial updates to a resource. PATCH is particularly useful when:
- You need to update a few fields of a resource.
- The resource is large, and sending the entire resource representation would be inefficient.
- You want to avoid accidentally overwriting other fields of the resource.
Idempotency of PUT and PATCH
While PATCH is not idempotent by default, you can design your PATCH operations to be idempotent by ensuring that applying the same PATCH request multiple times yields the same result. However, this requires careful consideration and implementation.
Idempotency in PUT:
- The PUT method is designed to replace the entire resource at the given URL with the provided data. If you send the same PUT request multiple times, the state of the resource remains the same after each request, making it idempotent.
Idempotency in PATCH:
The PATCH method is intended for partial updates, meaning it only changes specified fields of a resource. Whether PATCH is idempotent can depend on how the server handles the PATCH requests. If the server can guarantee that applying the same PATCH request multiple times will yield the same result, then PATCH can be considered idempotent. However, in practice, PATCH requests may not be idempotent because the partial update might rely on the current state of the resource. For example, if a PATCH request increments a counter, applying the same request multiple times would result in different states (e.g., incrementing the counter multiple times).
-
Idempotent PATCH Request
If the PATCH request is designed to set a specific field to a particular value, it can be idempotent.
PATCH /users/123 { "email": "newemail@example.com" }
This request sets the email field to "newemail@example.com". If you send this request multiple times, the email remains "newemail@example.com", making it idempotent.
-
Non-idempotent PATCH Request
If the PATCH request is designed to increment a field's value, it is not idempotent.
PATCH /users/123 { "incrementLoginCount": true }
This request increments the login count. Sending this request multiple times will increment the login count each time, resulting in different states.
The PATCH method is used to apply partial updates to a resource. It is efficient for updating specific fields without modifying the entire resource. Unlike PUT, PATCH does not require a complete resource representation and is designed for partial modifications. Use PATCH when you need to update only certain aspects of a resource, but be mindful of its non-idempotent nature by default.
DELETE
The DELETE method is used to delete a resource that's been identified by a URI. On successful deletion, return a HTTP status of 200 (OK) along with a response body, perhaps containing the representation of the deleted item. Otherwise, return a HTTP status of 204 (NO CONTENT) without a response body.
The DELETE method is idempotent because, regardless of how many times you call it, the outcome remains the same. If the resource is deleted successfully the first time, subsequent DELETE requests for the same resource will return a 404 (Not Found) status since the resource no longer exists. This is a caveat of the DELETE idempotent.
DELETE on an Item Endpoint
When you use DELETE on an item endpoint, it removes the specific resource identified by its ID. For example, to delete the user with ID 123, you would send a DELETE request to the /users/123
endpoint.
DELETE /users/123
If the deletion is successful, the server responds with a status indicating the outcome.
Response:
200 OK
{
"message": "User deleted successfully"
}
Alternatively, the server might respond with:
204 No Content
DELETE on a Collection Endpoint
Using DELETE on a collection endpoint typically is not recommended because it implies deleting all resources in the collection, which is usually not the intended action. Always specify the resource ID to avoid unintended mass deletions.
Handling Non-Existent Resources
If you attempt to delete a resource that does not exist, the server should return a 404 (Not Found) status.
Response:
404 Not Found
{
"error": "User not found"
}
The DELETE method is used to remove resources identified by a URI. It is idempotent, meaning multiple identical DELETE requests have the same effect as a single request. DELETE should be used on item endpoints to remove specific resources, and attempting to delete a non-existent resource should return a 404 status.
Non-CRUD Operations
Verb | Collection | Item | Idempotent | Responses |
---|---|---|---|---|
HEAD | ✔ | ✔ | ✔ | 200 (OK), returns only headers. 404 (Not Found), if id is invalid or not found. 400 (Bad Request), if a query parameter is invalid. |
OPTIONS | ✔ | ✔ | ✔ | 200 (OK), returns allowed HTTP methods. 404 (Not Found) if the resource does not exist. |
HEAD
The HEAD method is similar to GET, but it does not return a response body. It is used to retrieve the headers of a resource, which can be useful for checking if a resource exists or for retrieving metadata such as the Content-Type or Content-Length.
Why Use HEAD
The HEAD method is useful for:
- Checking Resource Existence: Before making a GET request, you can use HEAD to check if a resource exists.
- Retrieving Metadata: Get information about a resource without downloading the entire content.
HEAD on a Collection or Item Endpoint?
The HEAD method can be used on both item and collection endpoints. It retrieves the headers without a response body, making it useful for checking the existence of resources and retrieving metadata without the overhead of fetching the entire resource or collection.
HEAD /users/123
HEAD /users
If the resource exists, the server responds with headers but no body.
Response:
200 OK
Content-Type: application/json
Content-Length: 123
If the resource does not exist, the server responds with a 404 status.
Response:
404 Not Found
OPTIONS
The OPTIONS method is used to describe the communication options for the target resource. It returns the allowed HTTP methods and other options.
Why Use OPTIONS
The OPTIONS method is useful for:
- Discovering Supported Methods: Determine which HTTP methods are supported by a resource.
- CORS Preflight Requests: Commonly used in Cross-Origin Resource Sharing (CORS) to check which HTTP methods and headers are allowed.
OPTIONS on an Item Endpoint
When you use OPTIONS on an item endpoint, it retrieves the HTTP methods supported by the resource identified by its ID. For example, to find out what operations can be performed on the user with ID 123, you would send an OPTIONS request to the /users/123
endpoint.
OPTIONS /users/123
The server responds with the allowed methods.
Response:
200 OK
Allow: GET, POST, PUT, DELETE, OPTIONS
OPTIONS on a Collection Endpoint
Similarly, OPTIONS can be used on a collection endpoint to retrieve the allowed methods for the collection.
OPTIONS /users
Response:
200 OK
Allow: GET, POST, OPTIONS
The HEAD method is used to retrieve headers without a response body, useful for checking resource existence and metadata. The OPTIONS method describes the communication options for a resource, useful for discovering supported HTTP methods and CORS preflight requests.
Conclusion
In this article, we discussed how to use various HTTP methods on collection and item endpoints, compared them in terms of idempotency, and highlighted important considerations. Each method serves a unique purpose and use case, and using them correctly is crucial for the efficiency and stability of web applications.
- GET: Used to retrieve resources, and is both idempotent and safe.
- POST: Used to create new resources, and is not idempotent.
- PUT: Used to replace entire resources, and is idempotent.
- PATCH: Used to partially modify resources, and is not idempotent by default.
- DELETE: Used to remove resources, and is idempotent.
- HEAD: Used to retrieve headers without the response body, and is idempotent.
- OPTIONS: Used to describe communication options for a resource, and is idempotent.
Understanding the characteristics of each method and how to use them appropriately can prevent many issues in API design and implementation. By considering idempotency, you can ensure that requests work as intended and reduce unnecessary load. With this understanding, we hope you can build more stable and efficient web services.