Middleware System
Novaxjs2 provides a flexible middleware system for request processing, error handling, and response transformation. Middleware functions have access to the request and response objects and can execute any code, make changes to these objects, or end the request-response cycle.
Standard Middleware
Global middleware that runs for every request:
// Logging middleware
app.useMiddleware((req, res, next) => {
console.log(`${new Date().toISOString()} - ${req.method} ${req.url}`);
next(); // Call next middleware
});
// Authentication middleware
app.useMiddleware((req, res, next) => {
const token = req.headers.authorization;
if (token === 'secret-token') {
req.user = { id: 1, name: 'John Doe' };
next();
} else {
res.status(401).end('Unauthorized');
}
});
// Body parsing middleware (built-in)
// JSON and form data parsing is automatic in Novaxjs2
Error Middleware
Middleware that handles errors in the application:
// Error handling middleware
app.useErrorMiddleware((err, req, res, next) => {
console.error('Error:', err.stack);
// Custom error responses based on error type
if (err.statusCode === 404) {
return res.status(404).end('Page not found');
}
res.status(500).end('Internal Server Error');
});
// Async error handling
app.useErrorMiddleware(async (err, req, res, next) => {
// Log error to database or external service
await logErrorToService(err, req);
res.status(500).json({
error: 'Something went wrong',
requestId: req.id // Custom request ID
});
});
Built-in Middleware
Novaxjs2 includes several built-in middleware functions:
// Static file serving
app.serveStatic('public'); // Serve files from 'public' directory
// Automatic body parsing for:
// - JSON (application/json)
// - Form data (application/x-www-form-urlencoded)
// - Multipart form data (multipart/form-data) for file uploads
// CORS support
app.cors({
origins: ['https://example.com', 'http://localhost:3000'],
methods: 'GET, POST, PUT, DELETE, OPTIONS',
headers: 'Content-Type, Authorization',
credentials: true
});
Middleware Execution Order
Middleware executes in the order they are defined. Understanding the execution flow is crucial:
app.useMiddleware((req, res, next) => {
console.log('Middleware 1');
next();
});
app.useMiddleware((req, res, next) => {
console.log('Middleware 2');
next();
});
app.get('/', (req, res) => {
console.log('Route handler');
return 'Hello World';
});
// Execution order:
// 1. Middleware 1
// 2. Middleware 2
// 3. Route handler
Middleware Best Practices
- Always call
next()to pass control to the next middleware - Handle errors properly in error middleware
- Use async middleware for I/O operations
- Keep middleware focused on single responsibilities