HTTP Fundamentals
HTTP Methods — GET, POST, PUT, PATCH, DELETE
HTTP methods are the semantic verbs that define the interaction between a client and a resource on a server. Understanding these methods is critical for creating predictable, cacheable, and idempotent API interfaces that adhere to established standards. You reach for these methods whenever you need to perform specific CRUD operations on data resources within a RESTful architecture.
GET: Retrieving Resources
The GET method is the bedrock of HTTP interaction, designed solely for the retrieval of data. When you issue a GET request, you are telling the server that you intend to read a representation of a resource without triggering any state changes or side effects on the server side. Because of this read-only constraint, GET is considered a safe method, meaning it can be invoked repeatedly without altering the underlying data. Furthermore, GET requests are idempotent; multiple identical requests will produce the same result every time. This property allows intermediaries like web browsers, proxies, and content delivery networks to cache responses aggressively, significantly reducing server load and improving response times for the end user. When designing your API, always use GET for fetch operations to leverage these built-in performance benefits of the HTTP protocol.
# Fetching a specific user resource
# Request: GET /users/123
response = requests.get('https://api.example.com/users/123')
if response.status_code == 200:
user_data = response.json() # Resource retrieved successfullyPOST: Creating New Resources
Unlike GET, the POST method is fundamentally non-safe and non-idempotent because it is intended to trigger state changes. You use POST when you want to submit data to be processed by a specific resource, typically resulting in the creation of a new subordinate entity. When a client sends a POST request, the server is responsible for determining the structure of the newly created resource and generating a unique identifier for it. Because the server processes the data and creates something new each time, sending the same POST request multiple times will likely result in multiple new resources being created, hence its non-idempotent nature. This method is the primary vehicle for form submissions, database injections, and any workflow where a unique creation event needs to be recorded accurately within your system architecture.
# Creating a new resource
# Request: POST /users
payload = {'name': 'Jane Doe', 'email': 'jane@example.com'}
response = requests.post('https://api.example.com/users', json=payload)
# Status 201 indicates a new resource was createdPUT: Complete Resource Replacement
PUT is unique because it defines an idempotent operation for updating resources. When you send a PUT request, you are providing a full representation of the resource that should replace the current version residing at the specific URI. Because you are sending the complete state, repeating the request has no further impact on the resource state once it has been updated; the end result is always the state defined in your request payload. This makes PUT an excellent choice for scenarios where the client holds the authority over the resource's entire configuration. If the resource does not exist at the specified location, some APIs use PUT to perform a creation operation, but it is standard practice to treat it primarily as an absolute replacement tool to avoid unintended partial updates.
# Replacing a resource entirely
# Request: PUT /users/123
full_user = {'name': 'Jane Doe', 'email': 'jane.new@example.com', 'active': True}
response = requests.put('https://api.example.com/users/123', json=full_user)PATCH: Partial Resource Modification
PATCH provides a more granular approach to updates than PUT. While PUT requires sending the entire entity representation, PATCH allows you to send only the specific fields or properties that need to be modified. This is highly efficient when dealing with large objects where sending the full payload for a single field change would be wasteful of bandwidth. However, implementing PATCH requires careful consideration regarding idempotency. If the patch operation consists of a set of instructions, like incrementing a value, it may not be inherently idempotent. To ensure predictable behavior, developers often implement PATCH by applying atomic field updates that result in the same final state regardless of how many times the operation is executed in a short window. It is the preferred method for high-performance APIs requiring frequent, partial updates.
# Updating only specific fields
# Request: PATCH /users/123
update = {'email': 'updated.email@example.com'}
response = requests.patch('https://api.example.com/users/123', json=update)DELETE: Removing Resources
The DELETE method is the final piece of the CRUD cycle, used to request that the server remove the resource identified by the target URI. From a design perspective, DELETE is considered idempotent. This means that whether you send the request once or ten times, the end state is the same: the resource no longer exists on the server. If the first request succeeds in deleting the resource, subsequent requests might return a status code indicating that the resource is already gone, but the overall system remains in the target state of 'deleted'. It is vital to ensure that DELETE operations are authenticated and authorized correctly, as they are destructive by nature. When building your API, always provide a clear confirmation or standard response code to signify that the deletion intent has been successfully acknowledged and processed.
# Removing a resource
# Request: DELETE /users/123
response = requests.delete('https://api.example.com/users/123')
# Status 204 indicates success with no content to returnKey points
- GET is a safe and idempotent method used primarily for retrieving data without changing server state.
- POST is used to create new resources and is neither safe nor idempotent due to its side effects.
- PUT performs a complete replacement of a resource and must be treated as an idempotent operation.
- PATCH allows for partial modifications to a resource, which saves bandwidth compared to a full PUT request.
- DELETE is an idempotent method that removes a specific resource from the server's storage.
- Safe methods like GET should never trigger modifications to the data stored on the server.
- Idempotency ensures that multiple identical requests produce the same result as a single request.
- Selecting the correct HTTP method ensures that APIs behave in a predictable manner for all clients.
Common mistakes
- Mistake: Using GET to perform state-changing operations. Why it's wrong: GET requests are intended to be idempotent and safe, meaning they should not modify resources. Fix: Use POST, PUT, or PATCH for operations that alter server state.
- Mistake: Using POST to update resources when the operation is idempotent. Why it's wrong: POST is non-idempotent; repeated requests may create multiple duplicate resources. Fix: Use PUT for full resource replacement or PATCH for partial updates.
- Mistake: Returning 200 OK for every successful request. Why it's wrong: REST uses status codes to convey semantics; POST should return 201 Created for new resources, and DELETE should return 204 No Content. Fix: Map specific HTTP status codes to the outcome of the operation.
- Mistake: Treating PUT and PATCH as identical. Why it's wrong: PUT is meant for replacing the entire resource representation, while PATCH is for applying partial modifications. Fix: Use PUT for full updates and PATCH for granular attribute changes.
- Mistake: Embedding action verbs in URLs (e.g., /api/deleteUser). Why it's wrong: REST design relies on the HTTP verb to describe the action, keeping URLs as clean resource identifiers. Fix: Use nouns in URLs and let the HTTP method handle the intent.
Interview questions
What is the primary purpose of the GET method in a RESTful API design?
The GET method is used strictly to retrieve data from a server. In a RESTful architecture, it is defined as a safe and idempotent method, meaning it should never change the state of the resource it accesses. When a client performs a GET request, the server should return the requested resource representation, typically in JSON format, without performing any side effects on the backend database or resource stores.
How does the POST method differ from GET, and when should it be used?
Unlike GET, which is safe, the POST method is used to send data to the server to create a new resource. It is neither safe nor idempotent because calling it multiple times will typically result in the creation of multiple duplicate resources. For example, a POST request to '/api/users' adds a new user entry. The server returns a 201 Created status code to confirm that the new resource has been successfully instantiated.
Can you explain the difference between the PUT and PATCH methods when updating resources?
The PUT method is designed for full resource replacement. If you send a PUT request to update a user, you must provide the complete object, and the server replaces the existing resource entirely with the new payload. In contrast, the PATCH method is used for partial updates. You only send the specific fields that need to change, such as {'email': 'new@example.com'}, which is much more efficient for bandwidth and avoids accidental data loss during update operations.
What is the role of the DELETE method, and how should it behave in a REST API?
The DELETE method is used to remove a specific resource from the server. Once a client sends a DELETE request to a specific URL, such as '/api/orders/123', the server is expected to delete that resource. Upon successful deletion, the API should return a 200 OK or a 204 No Content status code. It is generally considered idempotent because deleting a resource that is already gone still results in the resource being absent.
Compare the use of PUT and POST when creating or updating resources in a design context.
The choice between PUT and POST depends on who assigns the resource identifier. With POST, the server typically decides the ID, which is common for resource collections. With PUT, the client usually specifies the URI of the resource, such as PUT '/api/products/item-001'. Use POST when you want the server to manage IDs to prevent collisions, and use PUT when the client has authority over the resource location, often used for idempotency-sensitive updates.
Why is the concept of idempotency so critical in REST API design, and which HTTP methods demonstrate it?
Idempotency ensures that performing the same request multiple times yields the same result as performing it once, which is vital for reliability in distributed systems where network failures occur. GET, PUT, PATCH, and DELETE are considered idempotent, while POST is not. For example, if a client experiences a timeout during a PUT request and retries, the final state remains the same, preventing inconsistent data states in the backend database.
Check yourself
1. An API consumer wants to update only the 'email' field of a user resource. Which method is most appropriate and semantically correct?
- A.GET
- B.POST
- C.PUT
- D.PATCH
Show answer
D. PATCH
PATCH is designed for partial updates to a resource. PUT requires sending the entire resource, and GET/POST do not semantically represent partial modification or are not the most efficient choice for updates.
2. Which HTTP method is required to be 'idempotent' but NOT 'safe'?
- A.GET
- B.POST
- C.PUT
- D.DELETE
Show answer
C. PUT
PUT is idempotent (multiple requests result in the same state) but unsafe (it changes state). GET is both safe and idempotent. POST is neither safe nor idempotent. DELETE is idempotent, but the question specifically targets the design property of PUT.
3. If a server receives a request to a collection URL that creates a new resource, which status code is the standard best practice for a successful response?
- A.200 OK
- B.201 Created
- C.204 No Content
- D.202 Accepted
Show answer
B. 201 Created
201 Created is the standard response for POST requests that successfully result in the creation of a new resource. 200 is too generic, 204 is for empty bodies, and 202 is for asynchronous processing.
4. Why is it considered bad REST design to use GET for a request that deletes a record from the database?
- A.GET requests are limited in string length
- B.GET requests should be safe and not cause side effects
- C.GET requests do not support authentication headers
- D.GET requests are always cached by the server
Show answer
B. GET requests should be safe and not cause side effects
GET is defined as a 'safe' method, meaning it should not change the state of the server. Using it to delete records violates this principle. Length limits and auth headers are implementation details, not REST design principles.
5. A client sends a PUT request to update a user's address. If the request is successful but the client repeats the exact same request again, what should be the resulting state?
- A.The server should return an error because it was already updated
- B.The resource should remain in the state it reached after the first request
- C.A second, duplicate resource should be created
- D.The server should delete the resource and recreate it
Show answer
B. The resource should remain in the state it reached after the first request
Because PUT is idempotent, subsequent identical requests should not change the state beyond the initial modification. Options suggesting error-throwing, duplication, or deletion misinterpret the definition of idempotency.