What is REST?
REST (Representational State Transfer) is an architectural style for designing networked applications. It uses HTTP requests to handle data operations, making it simple and scalable.
Core Principles
1. Stateless Communication
- Each request contains all necessary information
- No client context stored on server
- Improves scalability and reliability
- Easier to cache and debug
2. Standard HTTP Methods
# CRUD Operations
GET /api/users # Read users
POST /api/users # Create user
PUT /api/users/1 # Update user
DELETE /api/users/1 # Delete user
# Additional Methods
PATCH /api/users/1 # Partial update
HEAD /api/users # Get headers only
Implementation Examples
1. Basic REST API in Python
from flask import Flask, jsonify, request
app = Flask(__name__)
# GET endpoint
@app.route('/api/users', methods=['GET'])
def get_users():
return jsonify({
'users': users,
'total': len(users)
})
# POST endpoint
@app.route('/api/users', methods=['POST'])
def create_user():
user = request.json
users.append(user)
return jsonify(user), 201
# PUT endpoint
@app.route('/api/users/<int:user_id>', methods=['PUT'])
def update_user(user_id):
user = next((u for u in users if u['id'] == user_id), None)
if user:
user.update(request.json)
return jsonify(user)
return jsonify({'error': 'User not found'}), 404
2. Response Formats
// Success Response
{
"data": {
"id": 1,
"name": "John Doe",
"email": "[email protected]"
},
"meta": {
"timestamp": "2025-01-20T10:00:00Z"
}
}
// Error Response
{
"error": {
"code": "NOT_FOUND",
"message": "User not found",
"details": "No user exists with ID 123"
}
}
Best Practices
1. URL Structure
# Resource Hierarchy
/api/v1/users # User collection
/api/v1/users/{id} # Specific user
/api/v1/users/{id}/posts # User's posts
/api/v1/users/{id}/posts/{id} # Specific post
# Query Parameters
/api/v1/users?role=admin # Filtering
/api/v1/users?sort=name # Sorting
/api/v1/users?page=2&limit=10 # Pagination
2. Authentication
# JWT Authentication Example
from flask_jwt_extended import jwt_required, create_access_token
@app.route('/api/login', methods=['POST'])
def login():
username = request.json.get('username')
password = request.json.get('password')
if authenticate_user(username, password):
access_token = create_access_token(identity=username)
return jsonify({'token': access_token})
return jsonify({'error': 'Invalid credentials'}), 401
@app.route('/api/protected', methods=['GET'])
@jwt_required()
def protected_route():
return jsonify({'message': 'Access granted'})
3. Rate Limiting
from flask_limiter import Limiter
limiter = Limiter(
app,
key_func=get_remote_address,
default_limits=["200 per day", "50 per hour"]
)
@app.route('/api/users')
@limiter.limit("1 per second")
def get_users():
return jsonify(users)
Common Features
1. Pagination
@app.route('/api/users')
def get_users():
page = int(request.args.get('page', 1))
limit = int(request.args.get('limit', 10))
start = (page - 1) * limit
end = start + limit
return jsonify({
'data': users[start:end],
'meta': {
'total': len(users),
'page': page,
'limit': limit,
'pages': ceil(len(users) / limit)
}
})
2. Filtering and Sorting
@app.route('/api/users')
def get_users():
# Filtering
role = request.args.get('role')
if role:
filtered_users = [u for u in users if u['role'] == role]
# Sorting
sort_by = request.args.get('sort')
if sort_by:
filtered_users.sort(key=lambda x: x[sort_by])
return jsonify(filtered_users)
Security Considerations
1. Input Validation
from marshmallow import Schema, fields
class UserSchema(Schema):
name = fields.Str(required=True)
email = fields.Email(required=True)
age = fields.Int(validate=lambda n: n >= 0)
@app.route('/api/users', methods=['POST'])
def create_user():
schema = UserSchema()
try:
data = schema.load(request.json)
# Process validated data
return jsonify(data), 201
except ValidationError as err:
return jsonify(err.messages), 400
2. CORS Handling
from flask_cors import CORS
# Configure CORS
CORS(app, resources={
r"/api/*": {
"origins": ["https://allowed-domain.com"],
"methods": ["GET", "POST", "PUT", "DELETE"],
"allow_headers": ["Content-Type", "Authorization"]
}
})
Remember: A well-designed REST API should be intuitive, consistent, and secure while following established conventions and best practices.
