REST API Development

HTTP Methods & Status Codes Deep Dive

18 min Lesson 2 of 35

Understanding HTTP Methods in Depth

HTTP methods (also called verbs) are the backbone of REST API communication. Each method has specific semantics, safety properties, and idempotency characteristics that determine how it should be used. Let's explore each method in detail.

Note: Understanding the proper use of HTTP methods is crucial for building REST APIs that follow industry standards and are intuitive for other developers to use.

GET - Retrieve Resources

The GET method retrieves data from the server. It's the most commonly used HTTP method and should ONLY be used for reading data, never for modifying it.

Characteristics:

  • Safe: Doesn't change server state
  • Idempotent: Making the same request multiple times produces the same result
  • Cacheable: Responses can be cached by browsers and CDNs
  • Has Body: No request body (data passed in URL)

Common Use Cases:

// Get all users
GET /api/users
Response: 200 OK
[
  {"id": 1, "name": "Alice"},
  {"id": 2, "name": "Bob"}
]

// Get single user
GET /api/users/123
Response: 200 OK
{"id": 123, "name": "Alice", "email": "alice@example.com"}

// Get with query parameters (filtering, sorting, pagination)
GET /api/users?role=admin&sort=name&page=1&limit=20
Response: 200 OK
{
  "data": [...],
  "pagination": {
    "current_page": 1,
    "total_pages": 5,
    "total_items": 100
  }
}

// Get nested resources
GET /api/users/123/posts
Response: 200 OK
[
  {"id": 1, "title": "My First Post"},
  {"id": 2, "title": "Another Post"}
]
Warning: Never use GET for operations that modify data. URLs like GET /api/users/123/delete are a bad practice and a security risk (can be triggered by image tags or prefetch).

POST - Create Resources

POST is used to create new resources on the server. It sends data in the request body and typically returns the created resource with a 201 status code.

Characteristics:

  • Not Safe: Changes server state
  • Not Idempotent: Multiple identical requests create multiple resources
  • Not Cacheable: By default (can be made cacheable with proper headers)
  • Has Body: Yes - data sent in request body

Creating Resources:

POST /api/users
Content-Type: application/json

{
  "name": "Charlie",
  "email": "charlie@example.com",
  "role": "user"
}

Response: 201 Created
Location: /api/users/456
{
  "id": 456,
  "name": "Charlie",
  "email": "charlie@example.com",
  "role": "user",
  "created_at": "2026-02-14T10:30:00Z"
}
Tip: Always include a Location header in 201 responses pointing to the newly created resource. This follows REST best practices and helps clients know where to find the new resource.

POST for Complex Operations:

POST can also be used for operations that don't fit the standard CRUD model:

// Search with complex criteria (too complex for GET query params)
POST /api/users/search
{
  "filters": {
    "age_range": [18, 65],
    "countries": ["US", "UK", "CA"],
    "interests": ["tech", "sports"]
  }
}

// Process an action
POST /api/orders/123/ship
{
  "tracking_number": "ABC123",
  "carrier": "FedEx"
}

// Batch operations
POST /api/users/batch-create
{
  "users": [
    {"name": "User1", "email": "user1@example.com"},
    {"name": "User2", "email": "user2@example.com"}
  ]
}

PUT - Replace Entire Resource

PUT replaces an entire resource with the provided data. If the resource doesn't exist, some APIs create it (though this is optional).

Characteristics:

  • Not Safe: Changes server state
  • Idempotent: Multiple identical requests produce the same result
  • Not Cacheable: By default
  • Has Body: Yes - complete resource representation

Full Resource Updates:

PUT /api/users/123
Content-Type: application/json

{
  "name": "Alice Updated",
  "email": "alice.new@example.com",
  "role": "admin",
  "bio": "Software Developer"
}

Response: 200 OK
{
  "id": 123,
  "name": "Alice Updated",
  "email": "alice.new@example.com",
  "role": "admin",
  "bio": "Software Developer",
  "updated_at": "2026-02-14T11:00:00Z"
}
Important: With PUT, you must send ALL fields of the resource. Any fields not included will be removed or set to null. If you only want to update specific fields, use PATCH instead.

PATCH - Partial Updates

PATCH updates only specific fields of a resource without replacing the entire resource.

Characteristics:

  • Not Safe: Changes server state
  • Not Idempotent: Technically (though often implemented as idempotent)
  • Not Cacheable: By default
  • Has Body: Yes - only fields to update

Partial Updates:

PATCH /api/users/123
Content-Type: application/json

{
  "email": "alice.newest@example.com"
}

Response: 200 OK
{
  "id": 123,
  "name": "Alice Updated",  // unchanged
  "email": "alice.newest@example.com",  // updated
  "role": "admin",  // unchanged
  "bio": "Software Developer",  // unchanged
  "updated_at": "2026-02-14T11:15:00Z"
}

PUT vs. PATCH: When to Use Each

Scenario Use Reason
Update user profile (all fields) PUT Replacing entire resource
Change user email only PATCH Updating single field
Update product details form PUT Form has all fields
Toggle user active status PATCH Single boolean flip

DELETE - Remove Resources

DELETE removes a resource from the server permanently.

Characteristics:

  • Not Safe: Changes server state
  • Idempotent: Deleting the same resource multiple times has the same effect
  • Not Cacheable: By default
  • Has Body: Usually no (though technically allowed)

Deletion Patterns:

// Delete single resource
DELETE /api/users/123

Response: 204 No Content
// Empty body

// Or with confirmation data
Response: 200 OK
{
  "message": "User deleted successfully",
  "deleted_at": "2026-02-14T11:30:00Z"
}

// Soft delete (mark as deleted, don't remove)
DELETE /api/users/123
Response: 200 OK
{
  "id": 123,
  "deleted": true,
  "deleted_at": "2026-02-14T11:30:00Z"
}

// Delete nested resource
DELETE /api/users/123/posts/456
Response: 204 No Content
Tip: Consider implementing soft deletes for important resources. Instead of removing data from the database, mark it as deleted with a timestamp. This allows for data recovery and audit trails.

HEAD - Get Headers Only

HEAD is identical to GET but returns only headers without the response body. Useful for checking if a resource exists or getting metadata.

HEAD /api/users/123

Response: 200 OK
Content-Type: application/json
Content-Length: 256
Last-Modified: Wed, 14 Feb 2026 11:00:00 GMT
ETag: "abc123"
// No body returned

// Use cases:
// - Check if resource exists (200 vs 404)
// - Get resource size before downloading
// - Check if resource was modified (ETag, Last-Modified)
// - Verify authentication without downloading data

OPTIONS - Discover Allowed Methods

OPTIONS returns the HTTP methods that the server supports for a specific endpoint. Also used for CORS preflight requests.

OPTIONS /api/users/123

Response: 200 OK
Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS
Access-Control-Allow-Methods: GET, PUT, PATCH, DELETE
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Headers: Content-Type, Authorization

// CORS preflight example
OPTIONS /api/users
Origin: https://frontend.example.com

Response: 200 OK
Access-Control-Allow-Origin: https://frontend.example.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: Content-Type
Access-Control-Max-Age: 86400

HTTP Status Codes: Complete Reference

Status codes communicate the result of an HTTP request. Choosing the right code helps clients handle responses appropriately.

1xx - Informational Responses

These indicate that the request was received and is being processed. Rarely used in REST APIs.

Code Meaning Use Case
100 Continue Client should continue with request
101 Switching Protocols Switching to WebSocket, HTTP/2

2xx - Success Responses

The request was successfully received, understood, and accepted.

Code Meaning When to Use
200 OK GET, PUT, PATCH successful
201 Created POST created new resource
202 Accepted Request accepted, processing async
204 No Content DELETE successful, no data to return
206 Partial Content Range request (pagination, streaming)
// 200 OK - Standard success
GET /api/users/123
Response: 200 OK
{"id": 123, "name": "Alice"}

// 201 Created - New resource
POST /api/users
Response: 201 Created
Location: /api/users/456
{"id": 456, "name": "Bob"}

// 202 Accepted - Async processing
POST /api/reports/generate
Response: 202 Accepted
{"job_id": "abc123", "status": "processing"}

// 204 No Content - Success, no data
DELETE /api/users/123
Response: 204 No Content

3xx - Redirection Responses

Further action is needed to complete the request.

Code Meaning Use Case
301 Moved Permanently Resource permanently at new URL
302 Found Temporary redirect
304 Not Modified Cached version still valid
307 Temporary Redirect Temporary, keep same method
308 Permanent Redirect Permanent, keep same method

4xx - Client Error Responses

The request contains bad syntax or cannot be fulfilled. These are the most important codes for API developers.

Code Meaning When to Use
400 Bad Request Malformed request, invalid JSON
401 Unauthorized Missing or invalid authentication
403 Forbidden Authenticated but lacks permission
404 Not Found Resource doesn't exist
405 Method Not Allowed HTTP method not supported
409 Conflict Resource conflict (duplicate email)
422 Unprocessable Entity Validation failed
429 Too Many Requests Rate limit exceeded

Detailed 4xx Examples:

// 400 Bad Request - Malformed JSON
POST /api/users
{name: "Bob"}  // Missing quotes around key

Response: 400 Bad Request
{
  "error": "Invalid JSON syntax"
}

// 401 Unauthorized - No authentication
GET /api/users/123

Response: 401 Unauthorized
{
  "error": "Authentication required",
  "message": "Please provide a valid access token"
}

// 403 Forbidden - Insufficient permissions
DELETE /api/users/456

Response: 403 Forbidden
{
  "error": "Insufficient permissions",
  "message": "You don't have permission to delete users"
}

// 404 Not Found - Resource doesn't exist
GET /api/users/99999

Response: 404 Not Found
{
  "error": "User not found",
  "message": "No user exists with ID 99999"
}

// 409 Conflict - Duplicate resource
POST /api/users
{"email": "existing@example.com"}

Response: 409 Conflict
{
  "error": "Email already exists",
  "message": "A user with this email already exists"
}

// 422 Unprocessable Entity - Validation failed
POST /api/users
{"name": "A", "email": "invalid-email"}

Response: 422 Unprocessable Entity
{
  "error": "Validation failed",
  "errors": {
    "name": ["Name must be at least 3 characters"],
    "email": ["Email must be a valid email address"]
  }
}

// 429 Too Many Requests - Rate limit
GET /api/users

Response: 429 Too Many Requests
Retry-After: 60
{
  "error": "Rate limit exceeded",
  "message": "Try again in 60 seconds"
}

5xx - Server Error Responses

The server failed to fulfill a valid request.

Code Meaning When It Occurs
500 Internal Server Error Generic server error
502 Bad Gateway Invalid response from upstream
503 Service Unavailable Server overloaded or maintenance
504 Gateway Timeout Upstream server didn't respond
Warning: 5xx errors indicate problems with your server, not the client. Always log these for debugging and never expose sensitive error details to clients in production.
Exercise:

For each scenario, choose the correct HTTP method and expected status code:

  1. User updates their profile picture: Method: _____ Status: _____
  2. User logs in with email/password: Method: _____ Status: _____
  3. User checks if a username is available: Method: _____ Status: _____
  4. Admin soft-deletes a user account: Method: _____ Status: _____
  5. User tries to access admin panel without permission: Method: _____ Status: _____

Answers: 1) PATCH, 200 2) POST, 200 3) HEAD or GET, 200/404 4) DELETE, 200 5) GET, 403

Key Takeaways

  • GET is for reading, never modifying - it's safe and idempotent
  • POST creates resources and returns 201 with Location header
  • PUT replaces entire resources, PATCH updates specific fields
  • DELETE removes resources, returning 204 or 200
  • Use HEAD to check existence without downloading data
  • Always return appropriate status codes - they matter for clients
  • 4xx errors are client's fault, 5xx errors are server's fault
  • Include helpful error messages in response bodies
Next Lesson Preview: Now that you understand HTTP methods and status codes, we'll learn how to design clean, intuitive API endpoints with proper URL structure, naming conventions, and versioning strategies.