HTTP Status Codes: The Ones You Actually Need to Know
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
Locationheader. - 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-Authenticateheader. - 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
Locationheader to redirect clients to new locations. - Use the
WWW-Authenticateheader to authenticate clients. - Use rate limiting to prevent abuse and return 429 status codes when necessary.