Functional middleware lets you run code before your NestJS route handlers. It helps you add features like logging or checking user access simply.
Functional middleware in NestJS
import { Request, Response, NextFunction } from 'express'; export function myMiddleware(req: Request, res: Response, next: NextFunction) { // your code here next(); }
Functional middleware is a simple function with three parameters: request, response, and next.
Always call next() to pass control to the next middleware or route handler.
export function logger(req, res, next) {
console.log(`Request to: ${req.url}`);
next();
}export function checkAuth(req, res, next) {
if (!req.headers.authorization) {
return res.status(401).send('Unauthorized');
}
next();
}This example shows a functional middleware logger that logs every request's method and URL. It is applied to all routes in the app module. When you visit http://localhost:3000, the middleware logs the request, and the controller returns 'Hello World!'.
import { NestFactory } from '@nestjs/core'; import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common'; import { Request, Response, NextFunction } from 'express'; // Functional middleware to log requests export function logger(req: Request, res: Response, next: NextFunction) { console.log(`Request Method: ${req.method}, URL: ${req.url}`); next(); } // Simple controller import { Controller, Get } from '@nestjs/common'; @Controller() class AppController { @Get() getHello() { return 'Hello World!'; } } @Module({ controllers: [AppController], }) class AppModule implements NestModule { configure(consumer: MiddlewareConsumer) { consumer .apply(logger) // apply functional middleware .forRoutes('*'); // for all routes } } async function bootstrap() { const app = await NestFactory.create(AppModule); await app.listen(3000); console.log('Server running on http://localhost:3000'); } bootstrap();
Functional middleware is easy to write and use for simple tasks.
Remember to always call next() or the request will hang.
You can apply middleware to specific routes or all routes.
Functional middleware is a simple function that runs before route handlers.
It helps add features like logging, authentication, or modifying requests.
Always call next() to continue the request cycle.
Practice
Solution
Step 1: Understand middleware role
Middleware runs before route handlers to process requests or add features like logging or authentication.Step 2: Identify correct purpose
Options A, B, and D relate to other parts of development, not middleware.Final Answer:
To run code before the route handler to modify requests or add features -> Option AQuick Check:
Middleware runs before routes = C [OK]
- Confusing middleware with database models
- Thinking middleware creates UI components
- Believing middleware compiles code
Solution
Step 1: Check middleware signature
Functional middleware must accept (req, res, next) and call next() to continue.Step 2: Validate options
function logger(req, res, next) { console.log(req.url); next(); } matches this pattern. class Logger { log(req, res) { console.log(req.url); } } is a class, not functional middleware. const logger = () => { console.log('log'); } lacks parameters and next call. function logger(req, res) { console.log(req.url); } misses next parameter and call.Final Answer:
function logger(req, res, next) { console.log(req.url); next(); } -> Option DQuick Check:
Middleware needs (req, res, next) and calls next() [OK]
- Omitting the next parameter
- Not calling next() inside middleware
- Using class instead of function for functional middleware
function logger(req, res, next) {
console.log('Request URL:', req.url);
next();
}Solution
Step 1: Understand req.url property
In middleware, req.url contains the path of the incoming request, here '/home'.Step 2: Analyze console.log output
The middleware logs 'Request URL:' followed by req.url, so it prints 'Request URL: /home'.Final Answer:
Request URL: /home -> Option BQuick Check:
req.url logs request path = A [OK]
- Assuming next() stops console.log
- Thinking req.url is undefined
- Confusing middleware with route handler output
function auth(req, res, next) {
if (!req.headers.authorization) {
res.status(401).send('Unauthorized');
}
next();
}Solution
Step 1: Analyze flow after sending response
If authorization header is missing, response is sent with 401, but next() is still called, which can cause errors by continuing the request cycle.Step 2: Identify correct fix
To fix, add return before res.status(401).send(...) to stop execution or call next() only if authorized.Final Answer:
next() is called even after sending response, causing errors -> Option CQuick Check:
Call next() only if no response sent [OK]
- Calling next() after res.send causes errors
- Forgetting to stop middleware after response
- Misusing res.status vs res.sendStatus
Solution
Step 1: Confirm middleware signature and header setting
Middleware must accept (req, res, next) and call next() after setting headers. res.setHeader is correct method.Step 2: Evaluate options
function addVersion(req, res, next) { res.setHeader('X-App-Version', '1.0'); next(); } sets header then calls next() correctly. function addVersion(req, res) { res.setHeader('X-App-Version', '1.0'); } misses next parameter and call. function addVersion(req, res, next) { next(); res.setHeader('X-App-Version', '1.0'); } calls next() before setting header, so header may not be sent. function addVersion(req, res, next) { req.setHeader('X-App-Version', '1.0'); next(); } uses req.setHeader which is incorrect because req cannot set response headers.Final Answer:
function addVersion(req, res, next) { res.setHeader('X-App-Version', '1.0'); next(); } -> Option AQuick Check:
Set header before next() with correct method [OK]
- Calling next() before setting headers
- Omitting next parameter or call
- Confusing req and res when setting headers
Ready to prove it?
Pass the test and this pattern moves unknown
