MEHDI.
RETURN_TO_INDEX

HTTP Status Codes: The Ones You Actually Need to Know

7 min read
#Backend#Web Development#HTTP#API

Introduction

As a developer, I have worked with HTTP status codes for years, and I believe that understanding the most commonly used codes is crucial for effective communication between clients and servers. In this article, I will cover the essential HTTP status codes that I use daily.

Successful Responses

The 2xx status codes indicate that the request was successfully processed. Here are a few examples:

  • 200 OK: The request was successful, and the response body contains the requested data. For example, a GET request to retrieve a user's profile information might return a 200 status code with the user's data in the response body.
  • 201 Created: The request was successful, and a new resource was created. For example, a POST request to create a new user account might return a 201 status code with the newly created user's ID in the response body.
  • 204 No Content: The request was successful, but there is no content to return. For example, a DELETE request to delete a user account might return a 204 status code, indicating that the account was successfully deleted.

API Example

Here is an example of how you might use these status codes in an API:

from flask import Flask, jsonify

app = Flask(__name__)

# GET /users/:id
@app.route('/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
    user = User.query.get(user_id)
    if user:
        return jsonify(user.to_dict()), 200
    else:
        return jsonify({'error': 'User not found'}), 404

# POST /users
@app.route('/users', methods=['POST'])
def create_user():
    user = User(name='John Doe', email='[email protected]')
    db.session.add(user)
    db.session.commit()
    return jsonify({'id': user.id}), 201

# DELETE /users/:id
@app.route('/users/<int:user_id>', methods=['DELETE'])
def delete_user(user_id):
    user = User.query.get(user_id)
    if user:
        db.session.delete(user)
        db.session.commit()
        return '', 204
    else:
        return jsonify({'error': 'User not found'}), 404

Redirection

The 3xx status codes indicate that the request needs to be redirected to a different location. Here are a few examples:

  • 301 Moved Permanently: The requested resource has been permanently moved to a new location. For example, a GET request to a deprecated API endpoint might return a 301 status code with the new endpoint's URL in the Location header.
  • 304 Not Modified: The requested resource has not been modified since the last request. For example, a GET request to retrieve a cached resource might return a 304 status code, indicating that the cached version is still valid.

API Example

Here is an example of how you might use these status codes in an API:

from flask import Flask, redirect, url_for

app = Flask(__name__)

# GET /old-endpoint
@app.route('/old-endpoint', methods=['GET'])
def old_endpoint():
    return redirect(url_for('new_endpoint'), code=301)

# GET /new-endpoint
@app.route('/new-endpoint', methods=['GET'])
def new_endpoint():
    return 'Hello, World!', 200

# GET /cached-resource
@app.route('/cached-resource', methods=['GET'])
def cached_resource():
    # Check if the resource has been modified since the last request
    if not modified_since_last_request:
        return '', 304
    else:
        return 'Updated resource', 200

Client Errors

The 4xx status codes indicate that the request was invalid or cannot be processed. Here are a few examples:

  • 400 Bad Request: The request was invalid or malformed. For example, a POST request to create a new user account with invalid data might return a 400 status code with an error message in the response body.
  • 401 Unauthorized: The request requires authentication, but none was provided. For example, a GET request to retrieve a protected resource might return a 401 status code with a WWW-Authenticate header.
  • 403 Forbidden: The request is forbidden, even though the user is authenticated. For example, a GET request to retrieve a protected resource that the user does not have access to might return a 403 status code.
  • 404 Not Found: The requested resource was not found. For example, a GET request to retrieve a non-existent user account might return a 404 status code.
  • 409 Conflict: The request conflicts with the current state of the resource. For example, a PUT request to update a user account with a duplicate email address might return a 409 status code.
  • 422 Unprocessable Entity: The request was well-formed, but the data is invalid. For example, a POST request to create a new user account with invalid data might return a 422 status code with an error message in the response body.
  • 429 Too Many Requests: The request exceeds the rate limit. For example, a GET request to retrieve a resource that has been requested too many times in a short period might return a 429 status code.

API Example

Here is an example of how you might use these status codes in an API:

from flask import Flask, jsonify, request

app = Flask(__name__)

# POST /users
@app.route('/users', methods=['POST'])
def create_user():
    data = request.get_json()
    if not data:
        return jsonify({'error': 'Invalid request'}), 400
    elif not data.get('email'):
        return jsonify({'error': 'Email is required'}), 422
    elif User.query.filter_by(email=data['email']).first():
        return jsonify({'error': 'Email is already taken'}), 409
    else:
        user = User(name=data['name'], email=data['email'])
        db.session.add(user)
        db.session.commit()
        return jsonify({'id': user.id}), 201

# GET /protected-resource
@app.route('/protected-resource', methods=['GET'])
def protected_resource():
    if not request.headers.get('Authorization'):
        return jsonify({'error': 'Unauthorized'}), 401
    elif not user_has_access:
        return jsonify({'error': 'Forbidden'}), 403
    else:
        return 'Hello, World!', 200

Server Errors

The 5xx status codes indicate that the server encountered an error while processing the request. Here are a few examples:

  • 500 Internal Server Error: The server encountered an unexpected error. For example, a GET request to retrieve a resource might return a 500 status code if the server encounters a database error.
  • 502 Bad Gateway: The server received an invalid response from an upstream server. For example, a GET request to retrieve a resource from a third-party API might return a 502 status code if the third-party API returns an invalid response.
  • 503 Service Unavailable: The server is currently unavailable. For example, a GET request to retrieve a resource might return a 503 status code if the server is undergoing maintenance.

Practical Takeaways

When working with HTTP status codes, it is essential to remember that they are not just numbers, but a way to communicate with clients and other servers. Here are some key takeaways to keep in mind:

  • Use the correct status code for each request. For example, use 201 for created resources, 204 for deleted resources, and 404 for not found resources.
  • Include error messages in the response body for 4xx and 5xx status codes.
  • Use the Location header to redirect clients to new locations.
  • Use the WWW-Authenticate header to authenticate clients.
  • Use rate limiting to prevent abuse and return 429 status codes when necessary.