Middleware Pipeline
Last Updated: May 19, 2025
This document describes the middleware pipeline in the Typus Development Framework, which handles request processing and response generation.
Overview
The Typus Development Framework uses a middleware-based approach to process HTTP requests. Middleware functions are executed in a pipeline, with each middleware having the opportunity to process the request, modify it, and either pass it to the next middleware or terminate the request-response cycle.
This approach allows for:
- Separation of concerns - Each middleware handles a specific aspect of request processing
- Reusability - Middleware can be reused across different routes
- Extensibility - New middleware can be added to the pipeline without modifying existing code
- Configurability - Middleware can be conditionally applied based on routes or other criteria
Middleware Pipeline Flow
The request flows through a series of middleware before reaching the route handler, and then the response flows back through the middleware in reverse order:
Core Middleware
The framework includes several core middleware components that are applied to all requests:
Security Middleware
Provides security features such as:
- Helmet - Sets HTTP headers for security
- CORS - Handles Cross-Origin Resource Sharing
- Rate Limiting - Prevents abuse through request rate limiting
Body Parser
Parses request bodies into usable JavaScript objects:
- JSON Parser - Parses JSON request bodies
- URL-encoded Parser - Parses URL-encoded form data
Context Middleware
Establishes a request context that is available throughout the request lifecycle:
- Request ID - Assigns a unique ID to each request
- User Context - Stores authenticated user information
- Request Metadata - Stores request-specific data
Logging Middleware
Logs request and response information:
- Request Logging - Logs incoming request details
- Response Logging - Logs outgoing response details
- Error Logging - Logs errors that occur during request processing
Authentication Middleware
The authentication middleware verifies user identity:
- JWT Verification - Verifies JSON Web Tokens
- User Loading - Loads user information from the token
- Role Checking - Verifies user roles for authorization
// Example of using authentication middleware in a route
this.routes.get('/protected', [
this.auth(),
this.roles(['admin'])
], this.controller.protectedRoute.bind(this.controller));
Validation Middleware
The validation middleware ensures that request data meets the expected schema:
- Schema Validation - Validates request data against Zod schemas
- Data Transformation - Transforms data to the expected format
- Error Collection - Collects and formats validation errors
// Example of using validation middleware in a route
this.routes.post('/users', [
this.auth(),
this.controller.validate(userCreateSchema)
], this.controller.createUser.bind(this.controller));
Error Handling Middleware
The error handling middleware catches and processes errors that occur during request processing:
- Error Formatting - Formats errors into a consistent response structure
- Status Code Mapping - Maps error types to appropriate HTTP status codes
- Error Logging - Logs detailed error information
Custom Middleware
The framework supports custom middleware for specific use cases:
- File Upload Middleware - Handles file uploads using Multer
- Caching Middleware - Caches responses for improved performance
- Compression Middleware - Compresses responses for reduced bandwidth
Middleware Registration
Middleware can be registered at different levels:
Application-Level Middleware
Applied to all requests:
// In MiddlewareConfigurator.ts
this.app.use(helmet());
this.app.use(cors());
this.app.use(bodyParser.json({ limit: maxRequestSize }));
Router-Level Middleware
Applied to specific routers:
// In a module's initializeRoutes method
this.router.use(someMiddleware);
Route-Level Middleware
Applied to specific routes:
// In a module's initializeRoutes method
this.routes.get('/path', [middleware1, middleware2], handler);
Middleware Execution Order
The order of middleware execution is important:
- Application-Level Middleware - Executed first, in the order they are registered
- Router-Level Middleware - Executed next, in the order they are registered
- Route-Level Middleware - Executed last, in the order they are specified
BaseMiddleware Class
The framework provides a BaseMiddleware
class that serves as a foundation for custom middleware:
export abstract class BaseMiddleware {
constructor() {
// BaseMiddleware constructor logic here
}
abstract use(req: Request, res: Response, next: NextFunction): void;
}
Custom middleware can extend this class to ensure consistent implementation:
export class CustomMiddleware extends BaseMiddleware {
use(req: Request, res: Response, next: NextFunction): void {
// Custom middleware logic
next();
}
}
Middleware Configuration
The MiddlewareConfigurator
class handles the registration of application-level middleware:
public configure(): void {
// Security middleware
this.app.use(helmet({ /* options */ }));
this.app.use(cors());
// Body parsing middleware
this.app.use(bodyParser.json({ limit: maxRequestSize }));
this.app.use(bodyParser.urlencoded({ extended: true, limit: maxRequestSize }));
// Context middleware
this.app.use(ContextManager.getInstance().middleware());
// Logging middleware
this.app.use((req, res, next) => {
this.logger.info(`${req.method} ${req.path}`);
next();
});
}
Best Practices
Middleware Design
- Single Responsibility - Each middleware should focus on a specific task
- Error Handling - Always handle errors and pass them to the next middleware
- Performance - Keep middleware lightweight and efficient
- Composition - Compose complex middleware from simpler ones
Middleware Order
- Security First - Security middleware should be applied first
- Body Parsing - Body parsing middleware should be applied before validation
- Authentication - Authentication middleware should be applied before authorization
- Validation - Validation middleware should be applied before route handlers
Error Handling
- Catch All Errors - Ensure all errors are caught and handled
- Consistent Responses - Format error responses consistently
- Appropriate Status Codes - Use appropriate HTTP status codes for errors
- Detailed Logging - Log detailed error information for debugging
Conclusion
The middleware pipeline in the Typus Development Framework provides a flexible and extensible approach to request processing. By breaking down request handling into discrete middleware components, the framework promotes separation of concerns, reusability, and maintainability.
The combination of core middleware, authentication middleware, validation middleware, and error handling middleware ensures that requests are processed securely, validated properly, and errors are handled consistently.