Express.js and Middleware
Build production-style APIs with Express.js, routing, middleware, validation, centralized errors, and request lifecycle management.
Express Server and Routing
Express is a lightweight Node.js web framework that provides routing, middleware, request handling, and response helpers. It is commonly used to build REST APIs and web servers.
Routes map HTTP methods and URL patterns to handler functions.
import express from 'express';
const app = express();
app.use(express.json());
app.get('/users', (req, res) => {
res.json([{ id: 1, name: 'Suriya' }]);
});
app.post('/users', (req, res) => {
res.status(201).json(req.body);
});
app.listen(3000);- Express simplifies HTTP routing and middleware composition.
- Use routers to keep larger applications modular.
- Validate incoming request data instead of trusting client input.
Which Express middleware parses JSON request bodies?
Understanding Middleware
Express middleware functions receive req, res, and next. Middleware can inspect or modify requests, perform authentication, log requests, validate input, and terminate responses.
Middleware executes in registration order. Calling next() passes control to the next matching middleware or route handler.
function logger(req, res, next) {
const start = Date.now();
res.on('finish', () => {
console.log(req.method, req.originalUrl, Date.now() - start, 'ms');
});
next();
}
app.use(logger);- Middleware runs in registration order.
- Call
next()when middleware does not end the response. - Middleware is useful for cross-cutting concerns.
What happens when middleware calls `next()`?
Centralized Error Handling
Express applications should use centralized error handling instead of duplicating response logic throughout controllers. Error middleware has the signature (err, req, res, next).
Production systems should avoid exposing internal stack traces or secrets to clients. Errors should be logged with sufficient context while API responses contain safe information.
Never return database connection strings, access tokens, stack traces, or internal implementation details to untrusted clients.
app.use((err, req, res, next) => {
console.error(err);
if (res.headersSent) {
return next(err);
}
res.status(err.statusCode || 500).json({
error: err.publicMessage || 'Internal server error'
});
});- Centralize API error responses.
- Separate internal error details from public API messages.
- Handle errors consistently across asynchronous operations.
What distinguishes Express error-handling middleware?