HTTP Methods and Status Codes

Understanding the building blocks of RESTful API communication

Introduction to HTTP as an Application Protocol

HTTP (Hypertext Transfer Protocol) forms the foundation of data communication on the web. Originally designed for document transfer, it has evolved into a sophisticated application protocol that powers modern APIs.

In RESTful APIs, HTTP is more than just a transport mechanism—it's a rich protocol whose features are leveraged to create intuitive, standardized interfaces. Understanding HTTP methods and status codes thoroughly is essential for both designing and consuming APIs effectively.

Think of HTTP as a standardized language for communication between clients and servers, with:

This lecture will focus on HTTP methods and status codes, examining their semantic meaning, appropriate usage, and best practices in the context of RESTful APIs.

graph TD A[HTTP Request] --> B[Method] A --> C[Headers] A --> D[URL] A --> E[Body] F[HTTP Response] --> G[Status Code] F --> H[Headers] F --> I[Body] B --> J[GET, POST, PUT, DELETE, etc.] G --> K[1xx, 2xx, 3xx, 4xx, 5xx]

HTTP Methods in Depth

HTTP methods indicate the desired action to be performed on a resource. In RESTful APIs, they map to CRUD (Create, Read, Update, Delete) operations, but their semantics go deeper than this simple mapping.

GET: Retrieving Resources

GET is used to retrieve data from the server without modifying any resources.

Key Characteristics:


# Simple resource retrieval
GET /products/123 HTTP/1.1
Host: api.example.com
Accept: application/json

# Collection retrieval with filtering
GET /products?category=electronics&price_max=500 HTTP/1.1
Host: api.example.com
Accept: application/json
            

Real-world analogies: Reading a book from a library, looking up a phone number in a directory, or checking a price tag—all actions that retrieve information without changing it.

Common anti-patterns to avoid:

POST: Creating Resources

POST is primarily used to create new resources on the server.

Key Characteristics:


# Creating a new resource
POST /products HTTP/1.1
Host: api.example.com
Content-Type: application/json
Accept: application/json

{
  "name": "Ergonomic Keyboard",
  "price": 129.99,
  "category": "electronics",
  "description": "Comfortable typing experience with adjustable height."
}

# Response
HTTP/1.1 201 Created
Location: /products/456
Content-Type: application/json

{
  "id": 456,
  "name": "Ergonomic Keyboard",
  "price": 129.99,
  "category": "electronics",
  "description": "Comfortable typing experience with adjustable height.",
  "created_at": "2025-03-15T14:30:00Z"
}
            

Real-world analogies: Submitting a form to apply for a service, sending a letter, or placing an order at a restaurant—actions that create new entities or requests.

Secondary uses of POST:

Common anti-patterns to avoid:

PUT: Replacing Resources

PUT is used to update a resource by replacing it entirely with a new representation.

Key Characteristics:


# Updating a resource completely
PUT /products/456 HTTP/1.1
Host: api.example.com
Content-Type: application/json
Accept: application/json

{
  "name": "Ergonomic Mechanical Keyboard",
  "price": 149.99,
  "category": "electronics",
  "description": "Mechanical switches with adjustable height for maximum comfort."
}

# Response
HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": 456,
  "name": "Ergonomic Mechanical Keyboard",
  "price": 149.99,
  "category": "electronics",
  "description": "Mechanical switches with adjustable height for maximum comfort.",
  "created_at": "2025-03-15T14:30:00Z",
  "updated_at": "2025-03-15T16:45:00Z"
}
            

Real-world analogies: Replacing a file in a filing cabinet with a new version, or swapping out a part in a machine with a completely new part.

Common anti-patterns to avoid:

PATCH: Partial Updates

PATCH is used to make partial updates to a resource.

Key Characteristics:


# Simple partial update
PATCH /products/456 HTTP/1.1
Host: api.example.com
Content-Type: application/json
Accept: application/json

{
  "price": 139.99,
  "description": "Mechanical switches with ergonomic design and RGB lighting."
}

# JSON Patch format (RFC 6902)
PATCH /products/456 HTTP/1.1
Host: api.example.com
Content-Type: application/json-patch+json
Accept: application/json

[
  { "op": "replace", "path": "/price", "value": 139.99 },
  { "op": "replace", "path": "/description", "value": "Mechanical switches with ergonomic design and RGB lighting." }
]
            

Real-world analogies: Editing specific fields on a form, making corrections to a document, or adjusting specific settings on a device.

Patch document formats:

Common anti-patterns to avoid:

DELETE: Removing Resources

DELETE is used to remove a resource from the server.

Key Characteristics:


# Deleting a single resource
DELETE /products/456 HTTP/1.1
Host: api.example.com

# Response (no content)
HTTP/1.1 204 No Content

# Alternative response (with content)
HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": 456,
  "name": "Ergonomic Mechanical Keyboard",
  "deleted_at": "2025-03-16T09:20:00Z",
  "status": "deleted"
}
            

Real-world analogies: Removing a file from a filing cabinet, canceling a subscription, or deleting a contact from an address book.

Implementation considerations:


# Bulk deletion with query parameters
DELETE /products?category=discontinued HTTP/1.1
Host: api.example.com

# Bulk deletion with request body
DELETE /products HTTP/1.1
Host: api.example.com
Content-Type: application/json

{
  "ids": [123, 456, 789]
}
            

Common anti-patterns to avoid:

flowchart TB Resource[Resource Lifecycle] Create[Create Resource] Read[Read Resource] Update[Update Resource] Delete[Delete Resource] Resource --> Create Resource --> Read Resource --> Update Resource --> Delete Create --> POST Read --> GET Update --> PUT Update --> PATCH Delete --> DELETE style POST fill:#e6ffe6 style GET fill:#e6f7ff style PUT fill:#fff5e6 style PATCH fill:#ffeee6 style DELETE fill:#ffe6e6

Other HTTP Methods

While the five methods above are most common in RESTful APIs, several other HTTP methods exist and may be useful in specific circumstances.

Method Purpose RESTful API Use Cases
HEAD Like GET but returns only headers, no body
  • Checking if a resource exists
  • Getting resource metadata (size, modified date)
  • Checking cache validity
OPTIONS Returns the HTTP methods supported by the resource
  • CORS preflight requests
  • API self-discovery
  • Checking permissions on resources
CONNECT Establishes a tunnel to the server
  • Rarely used in RESTful APIs
  • More relevant for proxy servers
TRACE Performs a message loop-back test
  • Debugging request paths
  • Usually disabled in production for security

# Example OPTIONS request
OPTIONS /products/456 HTTP/1.1
Host: api.example.com

# Response
HTTP/1.1 200 OK
Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS
Access-Control-Allow-Methods: GET, PUT, PATCH, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
            

Method Properties Comparison

Method Safe Idempotent Cacheable Request Body Response Body
GET Yes Yes Yes No Yes
POST No No Rarely Yes Yes
PUT No Yes No Yes Yes
PATCH No No* No Yes Yes
DELETE No Yes No Maybe Maybe
HEAD Yes Yes Yes No No
OPTIONS Yes Yes No No Yes

* PATCH can be made idempotent through careful design of patch operations.

HTTP Status Codes in Depth

HTTP status codes are three-digit numbers returned by a server in response to a client's request. They indicate the outcome of the request and provide valuable context to the client.

Status codes are grouped into five classes, indicated by the first digit:

Informational Status Codes (1xx)

These codes indicate a provisional response. They are relatively rare in RESTful APIs.

Code Name Description API Use Cases
100 Continue Server has received the request headers and the client should proceed with the request body Large uploads, when the client wants to know if the server will accept the request before sending the entire body
101 Switching Protocols Server is switching protocols as requested by the client Upgrading from HTTP to WebSocket
102 Processing Server has received and is processing the request, but no response is available yet Long-running operations where the response cannot be generated quickly
103 Early Hints Used to return some response headers before final HTTP message Rarely used in APIs, more relevant for HTML document loading optimization

Success Status Codes (2xx)

These codes indicate that the client's request was successfully received, understood, and processed.

Code Name Description API Use Cases
200 OK Request succeeded, the response body contains the result GET requests, successful PUT/PATCH with response, POST operations that don't create a resource
201 Created Request succeeded and a new resource was created Successful POST requests that create new resources
202 Accepted Request has been accepted for processing, but the processing has not been completed Asynchronous operations, batch processing, long-running tasks
204 No Content Request succeeded, but there's no content to return in the response body Successful DELETE operations, operations that don't need to return data
205 Reset Content Request processed, the client should reset the document view Rarely used in APIs, more relevant for HTML form submissions
206 Partial Content Server is delivering only part of the resource due to a range header sent by the client Paginated responses, large file downloads, streaming media

# Example: 201 Created
POST /products HTTP/1.1
Host: api.example.com
Content-Type: application/json

{
  "name": "Wireless Mouse",
  "price": 49.99
}

HTTP/1.1 201 Created
Location: /products/789
Content-Type: application/json

{
  "id": 789,
  "name": "Wireless Mouse",
  "price": 49.99,
  "created_at": "2025-03-16T10:30:00Z"
}

# Example: 202 Accepted
POST /imports HTTP/1.1
Host: api.example.com
Content-Type: application/json

{
  "file_url": "https://example.com/data.csv",
  "options": { "replace_existing": true }
}

HTTP/1.1 202 Accepted
Content-Type: application/json
Location: /imports/job-12345

{
  "job_id": "job-12345",
  "status": "processing",
  "status_url": "/imports/job-12345"
}

# Example: 204 No Content
DELETE /products/789 HTTP/1.1
Host: api.example.com

HTTP/1.1 204 No Content
            

Redirection Status Codes (3xx)

These codes indicate that the client must take additional action to complete the request. In RESTful APIs, they're less common but still useful in specific scenarios.

Code Name Description API Use Cases
301 Moved Permanently The resource has been moved permanently to a new URL API versioning, resource restructuring, domain changes
302 Found The resource is temporarily located at a different URL Temporary redirects, load balancing, rarely used in APIs
303 See Other The response can be found at a different URL and should be retrieved using GET Redirecting after a POST operation to avoid duplicate submissions
304 Not Modified The resource hasn't been modified since the version specified by request headers Conditional GET requests with If-Modified-Since or If-None-Match headers
307 Temporary Redirect The request should be repeated with the same method at the given URL Temporary service migration, preserving the original HTTP method
308 Permanent Redirect The resource has been moved permanently, preserve the HTTP method Permanent API restructuring where the method must be preserved

# Example: 301 Moved Permanently
GET /api/v1/products/123 HTTP/1.1
Host: api.example.com

HTTP/1.1 301 Moved Permanently
Location: https://api.example.com/api/v2/products/123

# Example: 304 Not Modified
GET /products/123 HTTP/1.1
Host: api.example.com
If-Modified-Since: Sun, 15 Mar 2025 14:30:00 GMT
If-None-Match: "a1b2c3d4e5f6"

HTTP/1.1 304 Not Modified
ETag: "a1b2c3d4e5f6"
Last-Modified: Sun, 15 Mar 2025 14:30:00 GMT
Cache-Control: max-age=3600
            

Client Error Status Codes (4xx)

These codes indicate that the client seems to have made an error in the request. These are extremely important for providing clear feedback to API consumers.

Code Name Description API Use Cases
400 Bad Request The server cannot process the request due to a client error Malformed request syntax, invalid request message framing, or deceptive request routing
401 Unauthorized Authentication is required and has failed or has not been provided Missing or invalid authentication token, expired credentials
403 Forbidden Server understood the request but refuses to authorize it Authenticated user lacks permissions for the requested operation
404 Not Found The requested resource could not be found Resource doesn't exist, invalid IDs, non-existent endpoints
405 Method Not Allowed The HTTP method is not allowed for the requested resource Using DELETE on a read-only resource, using POST where only GET is permitted
406 Not Acceptable The server cannot produce a response matching the list of acceptable values in the Accept header Client requests a format (e.g., XML) that the API doesn't support
409 Conflict Request conflicts with the current state of the resource Concurrent updates, version conflicts, duplicate entries
410 Gone The resource requested is no longer available and will not be available again Accessing retired API versions, permanently removed resources
412 Precondition Failed Preconditions in the request header fields are not met Conditional requests with If-Match or If-Unmodified-Since headers
413 Payload Too Large Request entity is larger than limits defined by server File uploads exceeding size limits, request bodies that are too large
415 Unsupported Media Type The media format of the requested data is not supported Sending XML when only JSON is supported, unsupported Content-Type
422 Unprocessable Entity The request was well-formed but was unable to be followed due to semantic errors Validation failures, logical errors in request data
429 Too Many Requests The user has sent too many requests in a given amount of time Rate limiting, throttling to prevent abuse

# Example: 400 Bad Request
POST /products HTTP/1.1
Host: api.example.com
Content-Type: application/json

{ "name": "Product" }  # Missing required fields

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "error": {
    "code": "bad_request",
    "message": "The request could not be processed",
    "details": "Required field 'price' is missing"
  }
}

# Example: 401 Unauthorized
GET /users HTTP/1.1
Host: api.example.com

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer
Content-Type: application/json

{
  "error": {
    "code": "unauthorized",
    "message": "Authentication is required to access this resource"
  }
}

# Example: 403 Forbidden
DELETE /users/789 HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

HTTP/1.1 403 Forbidden
Content-Type: application/json

{
  "error": {
    "code": "forbidden",
    "message": "You don't have permission to delete this user"
  }
}

# Example: 422 Unprocessable Entity
POST /users HTTP/1.1
Host: api.example.com
Content-Type: application/json

{
  "name": "John Doe",
  "email": "not-an-email",
  "age": 17
}

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json

{
  "error": {
    "code": "validation_failed",
    "message": "The request contains invalid data",
    "details": [
      {
        "field": "email",
        "message": "Must be a valid email address"
      },
      {
        "field": "age",
        "message": "Must be at least 18"
      }
    ]
  }
}
            

Server Error Status Codes (5xx)

These codes indicate that the server failed to fulfill a valid request. While these should be rare, proper error handling is essential for a robust API.

Code Name Description API Use Cases
500 Internal Server Error A generic error message returned when an unexpected condition was encountered Uncaught exceptions, database errors, unexpected conditions
501 Not Implemented The server does not support the functionality required to fulfill the request Methods or features not yet implemented in the API
502 Bad Gateway The server received an invalid response from an upstream server API gateway errors, microservice communication failures
503 Service Unavailable The server is currently unavailable (because it is overloaded or down for maintenance) Temporary outages, maintenance windows, overload situations
504 Gateway Timeout The server was acting as a gateway or proxy and did not receive a timely response from the upstream server Timeouts in microservice communication, slow database responses

# Example: 500 Internal Server Error
POST /orders HTTP/1.1
Host: api.example.com
Content-Type: application/json

{
  "product_id": 123,
  "quantity": 5
}

HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{
  "error": {
    "code": "internal_error",
    "message": "An unexpected error occurred",
    "request_id": "req_abcd1234"
  }
}

# Example: 503 Service Unavailable
GET /products HTTP/1.1
Host: api.example.com

HTTP/1.1 503 Service Unavailable
Retry-After: 60
Content-Type: application/json

{
  "error": {
    "code": "service_unavailable",
    "message": "The service is temporarily unavailable due to maintenance",
    "estimated_availability": "2025-03-16T12:30:00Z"
  }
}
            
graph TD A[HTTP Status Codes] A --> B[1xx Informational] A --> C[2xx Success] A --> D[3xx Redirection] A --> E[4xx Client Error] A --> F[5xx Server Error] C --> C1[200 OK] C --> C2[201 Created] C --> C3[204 No Content] E --> E1[400 Bad Request] E --> E2[401 Unauthorized] E --> E3[403 Forbidden] E --> E4[404 Not Found] E --> E5[422 Unprocessable Entity] F --> F1[500 Internal Server Error] F --> F2[503 Service Unavailable] style C fill:#e6ffe6 style E fill:#ffe6e6 style F fill:#ffe0e0

Headers and Content Negotiation

HTTP headers allow clients and servers to exchange additional information about the request or response. They play a crucial role in content negotiation, caching, authentication, and more.

Common Request Headers

Header Purpose Example
Accept Indicates which content types the client can process Accept: application/json
Content-Type Indicates the media type of the request body Content-Type: application/json
Authorization Contains authentication credentials Authorization: Bearer eyJhbGciOiJIUzI1NiI...
User-Agent Identifies the client making the request User-Agent: MyAPIClient/1.0
Accept-Language Indicates the preferred languages for the response Accept-Language: en-US, en;q=0.8, fr;q=0.5
If-Modified-Since Makes the request conditional based on modification date If-Modified-Since: Sat, 15 Mar 2025 14:00:00 GMT
If-None-Match Makes the request conditional based on ETags If-None-Match: "a1b2c3d4e5"

Common Response Headers

Header Purpose Example
Content-Type Indicates the media type of the response body Content-Type: application/json; charset=utf-8
Cache-Control Directives for caching mechanisms Cache-Control: max-age=3600, public
ETag Identifier for a specific version of a resource ETag: "a1b2c3d4e5"
Location URL of a newly created resource or redirect target Location: /resources/123
WWW-Authenticate Indicates how to authenticate to access a resource WWW-Authenticate: Bearer realm="api"
X-RateLimit-Limit Rate limiting information (max requests) X-RateLimit-Limit: 100
X-RateLimit-Remaining Rate limiting information (remaining requests) X-RateLimit-Remaining: 87

Content Negotiation

Content negotiation allows clients and servers to agree on the format, language, or encoding of resources. This enables the same resource to be represented in different ways based on client preferences.

Content Type Negotiation


# Client requests JSON
GET /products/123 HTTP/1.1
Host: api.example.com
Accept: application/json

HTTP/1.1 200 OK
Content-Type: application/json

{ "id": 123, "name": "Product", "price": 99.99 }

# Client requests XML
GET /products/123 HTTP/1.1
Host: api.example.com
Accept: application/xml

HTTP/1.1 200 OK
Content-Type: application/xml

<product>
  <id>123</id>
  <name>Product</name>
  <price>99.99</price>
</product>
            

Language Negotiation


# Client requests English content
GET /products/123 HTTP/1.1
Host: api.example.com
Accept-Language: en-US, en;q=0.8

HTTP/1.1 200 OK
Content-Type: application/json
Content-Language: en-US

{
  "id": 123,
  "name": "Wireless Mouse",
  "description": "Comfortable wireless mouse with long battery life."
}

# Client requests French content
GET /products/123 HTTP/1.1
Host: api.example.com
Accept-Language: fr-FR, fr;q=0.8

HTTP/1.1 200 OK
Content-Type: application/json
Content-Language: fr-FR

{
  "id": 123,
  "name": "Souris sans fil",
  "description": "Souris sans fil confortable avec une longue durée de vie de la batterie."
}
            

Encoding Negotiation


# Client indicates it can accept compressed content
GET /products HTTP/1.1
Host: api.example.com
Accept-Encoding: gzip, deflate

HTTP/1.1 200 OK
Content-Type: application/json
Content-Encoding: gzip

[compressed JSON data]
            

Proper content negotiation enhances API flexibility and client compatibility, allowing different clients to interact with the API in their preferred format.

API Implementation Examples

Let's explore how HTTP methods and status codes work together in a RESTful API through concrete examples.

Example 1: CRUD Operations on a Product Resource


# Create a product
POST /products HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer token123

{
  "name": "Ergonomic Keyboard",
  "description": "Comfortable typing experience with adjustable height",
  "price": 129.99,
  "category_id": 5
}

HTTP/1.1 201 Created
Location: /products/456
Content-Type: application/json

{
  "id": 456,
  "name": "Ergonomic Keyboard",
  "description": "Comfortable typing experience with adjustable height",
  "price": 129.99,
  "category_id": 5,
  "created_at": "2025-03-16T14:30:00Z"
}

# Read a product
GET /products/456 HTTP/1.1
Host: api.example.com
Authorization: Bearer token123

HTTP/1.1 200 OK
Content-Type: application/json
ETag: "abc123"
Last-Modified: Sun, 16 Mar 2025 14:30:00 GMT

{
  "id": 456,
  "name": "Ergonomic Keyboard",
  "description": "Comfortable typing experience with adjustable height",
  "price": 129.99,
  "category_id": 5,
  "created_at": "2025-03-16T14:30:00Z"
}

# Update a product (full replacement)
PUT /products/456 HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer token123
If-Match: "abc123"

{
  "name": "Ergonomic Mechanical Keyboard",
  "description": "Mechanical switches with adjustable height for maximum comfort",
  "price": 149.99,
  "category_id": 5
}

HTTP/1.1 200 OK
Content-Type: application/json
ETag: "def456"

{
  "id": 456,
  "name": "Ergonomic Mechanical Keyboard",
  "description": "Mechanical switches with adjustable height for maximum comfort",
  "price": 149.99,
  "category_id": 5,
  "created_at": "2025-03-16T14:30:00Z",
  "updated_at": "2025-03-16T15:45:00Z"
}

# Partial update for just the price
PATCH /products/456 HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer token123

{
  "price": 139.99
}

HTTP/1.1 200 OK
Content-Type: application/json
ETag: "ghi789"

{
  "id": 456,
  "name": "Ergonomic Mechanical Keyboard",
  "description": "Mechanical switches with adjustable height for maximum comfort",
  "price": 139.99,
  "category_id": 5,
  "created_at": "2025-03-16T14:30:00Z",
  "updated_at": "2025-03-16T16:20:00Z"
}

# Delete a product
DELETE /products/456 HTTP/1.1
Host: api.example.com
Authorization: Bearer token123

HTTP/1.1 204 No Content
            

Example 2: Error Scenarios


# Attempt to create a product with invalid data
POST /products HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer token123

{
  "name": "X",
  "price": -10
}

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json

{
  "error": {
    "code": "validation_failed",
    "message": "The provided data failed validation",
    "details": [
      {
        "field": "name",
        "code": "too_short",
        "message": "Name must be at least 3 characters"
      },
      {
        "field": "price",
        "code": "invalid_value",
        "message": "Price must be greater than 0"
      },
      {
        "field": "category_id",
        "code": "required",
        "message": "Category ID is required"
      }
    ]
  }
}

# Attempt to access a non-existent resource
GET /products/999 HTTP/1.1
Host: api.example.com
Authorization: Bearer token123

HTTP/1.1 404 Not Found
Content-Type: application/json

{
  "error": {
    "code": "not_found",
    "message": "The requested product could not be found"
  }
}

# Attempt to update with invalid authentication
PUT /products/456 HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer invalid_token

HTTP/1.1 401 Unauthorized
Content-Type: application/json
WWW-Authenticate: Bearer error="invalid_token"

{
  "error": {
    "code": "invalid_token",
    "message": "The access token provided is expired, revoked, or invalid"
  }
}

# Attempt to delete without necessary permissions
DELETE /products/456 HTTP/1.1
Host: api.example.com
Authorization: Bearer token_without_delete_permission

HTTP/1.1 403 Forbidden
Content-Type: application/json

{
  "error": {
    "code": "insufficient_permissions",
    "message": "You do not have permission to delete this product"
  }
}

# Attempt to use an unsupported HTTP method
PATCH /products/bulk HTTP/1.1
Host: api.example.com
Authorization: Bearer token123

HTTP/1.1 405 Method Not Allowed
Content-Type: application/json
Allow: GET, POST

{
  "error": {
    "code": "method_not_allowed",
    "message": "The PATCH method is not supported for this resource",
    "allowed_methods": ["GET", "POST"]
  }
}
            

Example 3: Complex Operations


# Async operation: Import products
POST /imports HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer token123

{
  "source_url": "https://example.com/products.csv",
  "options": {
    "update_existing": true,
    "notify_on_completion": true
  }
}

HTTP/1.1 202 Accepted
Content-Type: application/json
Location: /imports/job-789

{
  "job_id": "job-789",
  "status": "queued",
  "status_url": "/imports/job-789",
  "estimated_completion_time": "2025-03-16T17:30:00Z"
}

# Check job status
GET /imports/job-789 HTTP/1.1
Host: api.example.com
Authorization: Bearer token123

HTTP/1.1 200 OK
Content-Type: application/json

{
  "job_id": "job-789",
  "status": "processing",
  "progress": 45,
  "processed_items": 450,
  "total_items": 1000,
  "started_at": "2025-03-16T17:00:00Z",
  "estimated_completion_time": "2025-03-16T17:25:00Z"
}

# Conditional request with caching
GET /products/456 HTTP/1.1
Host: api.example.com
Authorization: Bearer token123
If-None-Match: "ghi789"

HTTP/1.1 304 Not Modified
ETag: "ghi789"
Cache-Control: max-age=3600

# Bulk operation with partial failure
POST /products/bulk HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer token123

{
  "products": [
    {
      "name": "Product A",
      "price": 19.99,
      "category_id": 5
    },
    {
      "name": "Product B",
      "price": -5.00,
      "category_id": 5
    },
    {
      "name": "Product C",
      "price": 29.99,
      "category_id": 5
    }
  ]
}

HTTP/1.1 207 Multi-Status
Content-Type: application/json

{
  "status": "partial_success",
  "results": [
    {
      "index": 0,
      "status": 201,
      "id": 501,
      "message": "Created successfully"
    },
    {
      "index": 1,
      "status": 422,
      "message": "Validation failed",
      "errors": [
        {
          "field": "price",
          "message": "Price must be greater than 0"
        }
      ]
    },
    {
      "index": 2,
      "status": 201,
      "id": 502,
      "message": "Created successfully"
    }
  ],
  "summary": {
    "total": 3,
    "successful": 2,
    "failed": 1
  }
}
            

Common Implementation Pitfalls

When implementing HTTP methods and status codes in RESTful APIs, developers often encounter these common pitfalls:

Method Selection Issues

Status Code Misuse

HTTP Header Mistakes

Content Handling Issues

Security Considerations

Best Practices Summary

Based on our exploration of HTTP methods and status codes, here are key best practices to follow:

HTTP Method Usage

Status Code Selection

Content Handling

Security and Performance

Documentation

Practice Activities

Activity 1: Method and Status Code Matching

For each of the following scenarios, identify the most appropriate HTTP method and status code(s) to use:

  1. A client wants to retrieve a list of all products.
  2. A client wants to create a new user account.
  3. A client wants to update a user's email address only.
  4. A client wants to completely replace a product's information.
  5. A client tries to access a resource that doesn't exist.
  6. A client submits malformed JSON in a request.
  7. A client tries to access a protected resource without authentication.
  8. A client is authenticated but lacks permissions for an operation.
  9. A client submits valid data but it violates business rules (e.g., insufficient inventory).
  10. A client makes too many requests in a short time period.
  11. The server encounters an unexpected database error.
  12. A client tries to use a method not supported by the endpoint.
  13. A long-running operation is started but not yet complete.
  14. A client requests a resource that has been permanently removed.
  15. A client wants to check if their cached version of a resource is still current.

Activity 2: Error Response Design

Design appropriate error responses for the following situations, including status code and response body:

  1. A user registration form with multiple validation errors (username too short, invalid email format, passwords don't match)
  2. An attempt to access data from a user's account when logged in as a different user
  3. A payment processing failure due to insufficient funds
  4. A request to an API endpoint that has been deprecated and removed
  5. A database timeout during a resource-intensive query

Activity 3: HTTP Conversation Analysis

Analyze the following HTTP conversations, identify any issues, and suggest improvements:


# Conversation 1
POST /users/search HTTP/1.1
Content-Type: application/json

{
  "name": "John",
  "status": "active"
}

HTTP/1.1 200 OK
Content-Type: application/json

{
  "users": [
    {"id": 123, "name": "John Smith"},
    {"id": 456, "name": "John Doe"}
  ]
}

# Conversation 2
DELETE /articles/789 HTTP/1.1

HTTP/1.1 200 OK
Content-Type: application/json

{
  "message": "Article deleted successfully"
}

# Conversation 3
PUT /products/456 HTTP/1.1
Content-Type: application/json

{
  "price": 129.99
}

HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": 456,
  "name": "Wireless Keyboard",
  "description": "Ergonomic design",
  "price": 129.99
}

# Conversation 4
GET /orders HTTP/1.1

HTTP/1.1 401 Unauthorized
Content-Type: application/json

{
  "status": 401,
  "error": "You must be logged in to view orders"
}

# Conversation 5
POST /products HTTP/1.1
Content-Type: application/json

{
  "name": "New Product",
  "price": -10.00
}

HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{
  "error": "Validation failed: Price must be greater than 0"
}
            

Summary

In this lecture, we've explored the critical role of HTTP methods and status codes in RESTful API design:

Understanding HTTP methods and status codes is foundational for RESTful API design and development. By leveraging these standard mechanisms correctly, we create APIs that are intuitive, predictable, and aligned with web architecture principles.

Remember that HTTP is more than just a transport protocol—it's a rich application protocol with semantics that can greatly simplify API design when used correctly. The careful selection of methods and status codes serves as a form of documentation, helping API consumers understand what operations are possible and what has happened as a result of their requests.

Further Reading