A FastAPI backend service demonstrating custom HTTP middleware for request tracing, client-based rate limiting, and CORS configuration.
The project provides a /ping endpoint while implementing reusable middleware that manages request IDs and protects the API from excessive requests.
- Custom FastAPI middleware
- Request ID generation and propagation
- Client identification using
X-Client-Id - Sliding-window rate limiting
- HTTP 429 response when the rate limit is exceeded
- CORS configuration
- Configurable allowed origins
- UUID-based request tracing
- Environment-variable based configuration
- Python
- FastAPI
- Uvicorn
- Starlette Middleware
- UUID
- Collections
deque
Client
|
| HTTP Request
↓
Request Context Middleware
|
| Generate / preserve X-Request-ID
↓
Rate Limiting Middleware
|
| Check X-Client-Id
| Remove expired timestamps
| Enforce request limit
↓
CORS Middleware
|
↓
/ping Endpoint
|
↓
JSON Response
The API uses an in-memory sliding-window rate limiter.
Current configuration:
Maximum requests: 11
Time window: 10 seconds
Each client is identified using the X-Client-Id request header.
Example:
X-Client-Id: client-123For every request, the service:
- Retrieves the client's request history.
- Removes timestamps older than the configured window.
- Checks the number of remaining requests.
- Rejects the request with HTTP 429 if the limit has been reached.
- Otherwise records the current timestamp and processes the request.
Clients can provide their own request ID:
X-Request-ID: abc-123If the header is not provided, the server generates a UUID automatically.
The request ID is returned in the response:
X-Request-ID: abc-123This makes it possible to correlate requests across logs and services.
Returns the configured email and request ID.
Example response:
{
"email": "example@example.com",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}When a client exceeds the configured rate limit:
HTTP/1.1 429 Too Many RequestsResponse:
{
"detail": "Rate limit exceeded"
}The API allows requests only from configured origins.
Allowed origins can be configured in the application:
ALLOWED_ORIGINS = [
"https://example.com"
]The API supports:
- GET
- OPTIONS
and explicitly allows the headers required by the application.
The service supports environment-based configuration.
Example:
EMAIL=example@example.comUsing environment variables avoids hard-coding configuration values into the application.
Clone the repository:
git clone <your-repository-url>
cd fastapi-rate-limiterCreate a virtual environment:
python -m venv venvActivate it on Windows:
venv\Scripts\activateInstall dependencies:
pip install fastapi uvicornStart the application:
uvicorn main:app --reloadThe API will be available at:
http://127.0.0.1:8000
Test the endpoint:
http://127.0.0.1:8000/ping
Send repeated requests with the same client ID:
X-Client-Id: client-123The first 11 requests within the 10-second window are allowed.
Once the limit is exceeded, the API returns:
429 Too Many Requests
After requests expire from the sliding window, new requests are allowed again.
fastapi-rate-limiter/
│
├── main.py
├── requirements.txt
├── .gitignore
└── README.md
The current implementation stores rate-limit information in application memory.
For a distributed production deployment with multiple API instances, a shared store such as Redis would be more appropriate.
Possible production improvements include:
- Redis-based distributed rate limiting
- Authentication and authorization
- Structured logging
- Request metrics
- Prometheus monitoring
- Docker deployment
- Automated tests
- Configurable rate limits
- IP-based fallback identification
Retry-Afterresponse headers
Basabdutta Konar