Under The Hood
backend nestjs NestJS 10+

Guards: CanActivate, Reflector Metadata, and Role-Based Authorization

Last updated
Prerequisites:
NestJS ExecutionContext
TypeScript Decorators & Metadata
  • nestjs
  • guards
  • canActivate
  • reflector
  • authorization
  • rbac

Read at your depth

The practical view

Guards determine whether a request should be handled by a route handler. They implement `CanActivate` with a `canActivate(context: ExecutionContext): boolean | Promise<boolean>`. If it returns `true`, the request proceeds; if `false`, NestJS returns `403 Forbidden`. Use `@UseGuards(AuthGuard)` at the controller or method level, or register globally with `APP_GUARD`.

The same idea in other frameworks

nestjs equivalent
`@UseGuards(RolesGuard)` implementing `CanActivate` with `Reflector`.

Legacy vs modern

Middleware Route Protection vs Declarative NestJS RBAC Guard

Express middleware requires hardcoded URL regex matching; NestJS Guards use declarative metadata decorators.

before → after
Imperative Middleware Check
if (req.path.startsWith('/admin') && req.user.role !== 'admin') res.status(403).send(); // ❌ Brittle regex routes
Declarative Roles Guard with Reflector
@Roles(Role.Admin) @UseGuards(RolesGuard) // ✅ NEW: Declarative, type-safe metadata

Interview gotchas

Context

This is one of the most frequently asked NestJS architectural lifecycle questions.

The mechanical answer

The exact incoming request execution order is: 1. **Global / Module Middleware** 2. **Guards** (Global -> Controller -> Route) 3. **Interceptors (Pre-controller logic)** 4. **Pipes** (Global -> Controller -> Route -> Parameter) 5. **Controller Route Handler** 6. **Interceptors (Post-controller RxJS response mapping)** 7. **Exception Filters** (if an error is thrown anywhere)

Trap

Guards run *before* Pipes. This means parameter validation and type transformation have not occurred yet when a Guard executes.

Under The Hood — a multi-depth technical interview hub.

Third-party licenses Press ⌘ K to search.