| Level Navigation: 1 | 2 | 3 | (4ℹ️) | (5ℹ️) | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14⚡ | 15⚡ | (16ℹ️) | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26⚡ | 27⚡ | 28⚡ | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39⚡ | 40⚡ |
Add validation and consistent error handling to your API.
400 on bad input.{ "error": "message" }.
// Validate multiple required fields
app.post('/items', (req, res) => {
if (!req.body?.title) {
return res.status(400).json({ error: 'Title is required' });
}
if (!req.body?.price) {
return res.status(400).json({ error: 'Price is required' });
}
if (typeof req.body.price !== 'number' || req.body.price < 0) {
return res.status(400).json({ error: 'Price must be a positive number' });
}
// If validation passes, create the item
const newItem = { ...req.body, id: randomUUID() };
itemsStorage.push(newItem);
res.status(201).json(newItem);
});
// Create a helper function for consistent error responses
function sendError(res, statusCode, message) {
return res.status(statusCode).json({ error: message });
}
// Use it in your routes
app.post('/items', (req, res) => {
if (!req.body?.title) {
return sendError(res, 400, 'Title is required');
}
// ... rest of route
});
app.get('/items/:id', (req, res) => {
const item = itemsStorage.find(entry => entry.id === req.params.id);
if (!item) {
return sendError(res, 404, 'Item not found');
}
res.json(item);
});
// Add timing middleware before your routes
app.use((req, res, next) => {
const start = Date.now();
// Log after response is sent
res.on('finish', () => {
const duration = Date.now() - start;
console.log(`${req.method} ${req.path} - ${res.statusCode} - ${duration}ms`);
});
next();
});
What is middleware?
Middleware functions are functions that have access to the request object (req), the response object (res), and the next function in the application’s request-response cycle. Middleware can execute code, make changes to the request and response objects, end the request-response cycle, or call the next middleware function.
The Request-Response Cycle:
When a request comes in, Express passes it through middleware functions in the order they are defined. Each middleware can:
next() to pass control to the next middlewareExample: How express.json() Works
// This middleware runs for every request
app.use(express.json());
// What it does:
// 1. Checks if request has Content-Type: application/json
// 2. Reads the request body
// 3. Parses it from JSON string to JavaScript object
// 4. Attaches it to req.body
// 5. Calls next() to continue to your route handlers
Types of Middleware:
app.use(express.json()); // Parse JSON bodies
app.use((req, res, next) => {
console.log('Request received:', req.method, req.path);
next();
});
app.post('/items', validateItem, (req, res) => {
// validateItem is middleware that runs before this handler
});
app.use((err, req, res, next) => {
console.error(err);
res.status(500).json({ error: 'Something went wrong' });
});
Why Use Middleware?
Common Middleware Patterns: