Community Question Bundle
Express vs NestJS Middleware Quiz
Four questions comparing Express middleware to NestJS guards, interceptors, and pipes. Aimed at devs who came up on Express and keep reaching for `app.use()` when Nest already gives them a better seam.
Express vs NestJS Middleware Quiz
Four questions comparing Express middleware to NestJS guards, interceptors, and pipes. Aimed at devs who came up on Express and keep reaching for `app.use()` when Nest already gives them a better seam.
By @isabellarashid
December 30, 2025
·
Updated May 20, 2026
925 views
20
Rate
An Express middleware does auth and calls next() after attaching req.user. Port this to NestJS: should it be a Middleware, a Guard, or an Interceptor, and why?
Live example
Live example:
// Route protected by @UseGuards(AuthGuard):
// GET /me (no Authorization header) -> 401 UnauthorizedException
// GET /me (valid token) -> handler runs, request.user = { id: 'u_1' }
// @Roles('admin') decorator on the handler is readable by the guard via Reflector,
// because Guards run AFTER route resolution (unlike Middleware).A team wraps every handler with a try / catch and emits a structured error response. They want to centralize this. What is the Express idiom and what is the NestJS idiom, and where does the Nest version run in the lifecycle?
Live example
Live example with the filter applied:
// Handler throws new HttpException('not found', 404)
// -> AllExceptionsFilter catches it, response is { error: 'not found' } with status 404
// Handler throws new Error('boom')
// -> filter falls back to 500, response is { error: 'boom' }
//
// Express equivalent: app.use((err, req, res, next) => ...) registered LAST.
// The 4-arg signature is how Express recognizes it as an error handler.Express devs reach for body-parser or express.json(). The Nest dev says you do not need that. Walk through what Nest does automatically, and where validation actually lives compared to Express.
Live example
Live example with ValidationPipe registered globally:
// POST /users with { "email": "bad" }
// -> 422 before UsersController.create runs (class-validator rejects)
// POST /users with { "email": "[email protected]" }
// -> handler runs with dto.email typed and validatedA reviewer wants response logging that prints the path, status, and duration. In Express they would slap on morgan. In NestJS the team is debating Middleware vs Interceptor. Which one captures the status code reliably, and what is the gotcha if you pick the wrong one?
Live example
Live example:
// LoggingInterceptor with tap() after next.handle():
// GET /orders/42 -> 200 in 35ms -> logs 'GET /orders/42 200 35 ms'
// Handler throws -> tap callback does NOT fire; pair with an Exception Filter
// to cover the error path.
//
// Middleware version: res.statusCode is still the default at the time middleware runs,
// so you'd log '200' even when the response ends up 500.