What are Middlewares?
Middlewares in Definable are components that process HTTP requests and responses at the global level. They wrap around the request handling process, allowing code to be executed:- Before the request is processed by the route handlers
- After the route handler generates a response
Middleware Implementation
Definable middlewares are implemented using StarletteβsBaseHTTPMiddleware
class, which FastAPI inherits from. Each middleware follows a consistent pattern:
Middleware Registration
Middlewares are automatically discovered and registered in the FastAPI application by theManager
class, which scans the middlewares
directory for Python files:
Middleware Stack
Middlewares are executed in the reverse order they are added to the FastAPI application. The current middleware stack in Definable is:- CORS Middleware - Added directly in
app.py
for handling Cross-Origin Resource Sharing - RateLimiting Middleware - Limits the number of requests per client IP
- Exceptions Middleware - Global exception handling and formatting
The middleware stack order is important as it determines both the pre-processing and post-processing execution sequence. CORS middleware is executed first for pre-processing but last for post-processing.
Core Middlewares
Exception Handling Middleware
Theexceptions.py
middleware provides centralized error handling for the application:
- Catches all unhandled exceptions from route handlers
- Provides detailed error information in development mode
- Logs exceptions with full stack trace
- Returns simplified error messages in production
Rate Limiting Middleware
Theratelimit.py
middleware implements a sliding window rate limiter to prevent API abuse:
- Implements a sliding window algorithm rather than a fixed time bucket
- Tracks requests per client IP address
- Configurable maximum requests and time window
- Returns HTTP 429 (Too Many Requests) when rate limit is exceeded
CORS Middleware
The Cross-Origin Resource Sharing middleware is added directly inapp.py
:
- Controls which domains can access the API
- Configures allowed HTTP methods and headers
- Manages preflight requests automatically
- Essential for browser-based clients accessing the API
Middleware vs. Dependencies
Definable uses both middlewares and FastAPI dependencies to handle cross-cutting concerns, but they serve different purposes:Middlewares
- Global scope: Applied to all requests
- Pre/post processing: Can modify both requests and responses
- Application-level concerns: Logging, error handling, rate limiting
- No access to route-specific details: Limited context about the specific endpoint
Dependencies (like RBAC
and JWTBearer
)
- Route-specific: Applied only to routes that declare them
- Integrated with OpenAPI: Included in API documentation
- Request-specific validation: Can validate and extract route-specific data
- Type safety: Provide type hints for route handlers
Creating New Middlewares
To add a new middleware to the Definable backend:- Create a new file in the
src/middlewares/
directory - Implement a class named
Middleware
that inherits fromBaseHTTPMiddleware
- Implement the
__init__
anddispatch
methods - The middleware will be automatically discovered and registered
Middleware Best Practices
When working with middlewares in Definable, follow these best practices:- Keep middlewares focused: Each middleware should have a single responsibility
- Minimize middleware overhead: Optimize performance-critical code
- Handle exceptions: Catch and handle exceptions within the middleware
- Use dependency injection: Leverage the
Acquire
class for dependencies - Consider order: Be aware of middleware execution order
- Prefer dependencies for route-specific concerns: Use FastAPI dependencies instead of parsing route data in middlewares
Performance Considerations
Middlewares run for every request, so they can impact API performance:- Memory usage: Avoid storing large amounts of data in middleware instances
- Computation overhead: Minimize complex calculations in the request path
- Database access: Avoid database queries in middlewares when possible
- Caching: Consider caching results for expensive operations
Security Middlewares
While authentication in Definable is primarily handled by dependencies (JWTBearer
and RBAC
), security-related middlewares could be added for:
- IP filtering: Blocking requests from suspicious IPs
- Request validation: Scanning for malicious patterns
- Response headers: Adding security headers like CSP, HSTS
- Request throttling: More advanced rate limiting strategies