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:

Client

Request

Security Middleware

Body Parser

Context Middleware

Logging Middleware

Auth Middleware

Validation Middleware

Route Handler

Response

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:

  1. Application-Level Middleware - Executed first, in the order they are registered
  2. Router-Level Middleware - Executed next, in the order they are registered
  3. 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

  1. Single Responsibility - Each middleware should focus on a specific task
  2. Error Handling - Always handle errors and pass them to the next middleware
  3. Performance - Keep middleware lightweight and efficient
  4. Composition - Compose complex middleware from simpler ones

Middleware Order

  1. Security First - Security middleware should be applied first
  2. Body Parsing - Body parsing middleware should be applied before validation
  3. Authentication - Authentication middleware should be applied before authorization
  4. Validation - Validation middleware should be applied before route handlers

Error Handling

  1. Catch All Errors - Ensure all errors are caught and handled
  2. Consistent Responses - Format error responses consistently
  3. Appropriate Status Codes - Use appropriate HTTP status codes for errors
  4. 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.

WARNING

Failed to fetch dynamically imported module: https://typus.dev/assets/RecursiveNavItem-Cep7andh.js

{ "stack": "AppError: Failed to fetch dynamically imported module: https://typus.dev/assets/RecursiveNavItem-Cep7andh.js\n at https://typus.dev/assets/index-DS79FI73.js:315:420\n at dn (https://typus.dev/assets/vue-vendor-Ct83yDeK.js:13:1385)\n at We (https://typus.dev/assets/vue-vendor-Ct83yDeK.js:13:1455)\n at Ws.t.__weh.t.__weh (https://typus.dev/assets/vue-vendor-Ct83yDeK.js:14:7364)\n at jt (https://typus.dev/assets/vue-vendor-Ct83yDeK.js:13:1866)\n at v (https://typus.dev/assets/vue-vendor-Ct83yDeK.js:14:4019)\n at https://typus.dev/assets/vue-vendor-Ct83yDeK.js:14:4097" }