Bird
Raised Fist0
NestJSframework~10 mins

Guard binding levels in NestJS - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Guard binding levels
Request Received
↓
Global Guards Check
↓
Controller Guards Check
↓
Route Handler Guards Check
↓
If All Guards Pass
↓
Execute Route Handler
↓
Send Response
This flow shows how NestJS checks guards at global, controller, and route levels in order before running the route handler.
Execution Sample
NestJS
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    return true; // allow access
  }
}
This code defines a simple guard that always allows access.
Execution Table
StepGuard LevelGuard Called?ResultNext Action
1GlobalYesPassCheck Controller Guards
2ControllerYesPassCheck Route Guards
3RouteYesPassExecute Route Handler
4RouteNo more guardsN/ASend Response
💡 All guards passed, so route handler executes and response is sent.
Variable Tracker
VariableStartAfter Global GuardAfter Controller GuardAfter Route GuardFinal
accessAllowedundefinedtruetruetruetrue
Key Moments - 3 Insights
Why does NestJS check global guards before controller or route guards?
Global guards apply to every request, so they run first to quickly allow or deny access before more specific guards run, as shown in steps 1 and 2 of the execution_table.
What happens if a controller guard denies access?
If a controller guard returns false, NestJS stops checking further guards and denies the request immediately, skipping route guards and handler execution. This is implied by the flow and exit conditions.
Can route-level guards override global or controller guards?
No, route guards run last and cannot override earlier guards. If any previous guard denies access, route guards won't run. This order is clear in the concept_flow and execution_table.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, at which step are controller guards checked?
AStep 3
BStep 1
CStep 2
DStep 4
💡 Hint
Check the 'Guard Level' column in execution_table rows.
According to variable_tracker, what is the value of accessAllowed after the route guard?
Atrue
Bfalse
Cundefined
Dnull
💡 Hint
Look at the 'After Route Guard' column for accessAllowed in variable_tracker.
If the global guard fails, what happens next according to the concept_flow?
AController guards run anyway
BRequest is denied immediately
CRoute handler executes
DRoute guards run
💡 Hint
Refer to the concept_flow where failure at any guard level stops further processing.
Concept Snapshot
NestJS checks guards in this order:
1. Global guards run first for all requests.
2. Controller guards run next for specific controllers.
3. Route guards run last for specific routes.
If any guard denies access, request stops immediately.
Guards control access before route handler runs.
Full Transcript
In NestJS, guards are functions that decide if a request can continue. They run in a specific order: global guards first, then controller guards, then route guards. If any guard returns false, NestJS stops and denies the request. This ensures security checks happen from broad to specific. The example shows a guard that always allows access. The execution table traces each guard check step by step. The variable tracker shows how the accessAllowed flag stays true after each guard. Key moments clarify why the order matters and what happens if a guard denies access. The quiz tests understanding of guard order and outcomes.

Practice

(1/5)
1. Which of the following is true about guard binding levels in NestJS?
easy
A. Route guards apply to all controllers automatically.
B. Global guards apply to all routes in the application.
C. Controller guards cannot be overridden by route guards.
D. Guards can only be applied globally, not to specific routes.

Solution

  1. Step 1: Understand global guard scope

    Global guards are set once and protect every request in the app.
  2. Step 2: Compare with other guard levels

    Route guards apply only to specific routes, and controller guards apply to all routes in a controller. Route guards can override controller guards.
  3. Final Answer:

    Global guards apply to all routes in the application. -> Option B
  4. Quick Check:

    Global guard = all routes [OK]
Hint: Global guards protect all routes, no exceptions [OK]
Common Mistakes:
  • Thinking route guards apply globally
  • Believing controller guards cannot be overridden
  • Assuming guards can't be applied to routes
2. Which is the correct way to bind a guard to a specific route in NestJS?
easy
A. Use @GlobalGuard decorator on the route
B. @UseGuards(MyGuard) above the controller class
C. Add MyGuard to the global providers array
D. @UseGuards(MyGuard) above the route handler method

Solution

  1. Step 1: Identify route-level guard binding

    To bind a guard to a specific route, place @UseGuards() decorator above the route handler method.
  2. Step 2: Differentiate from other bindings

    @UseGuards() above the controller binds to all routes in that controller. Global guards are set differently, and @GlobalGuard does not exist.
  3. Final Answer:

    @UseGuards(MyGuard) above the route handler method -> Option D
  4. Quick Check:

    Route guard = @UseGuards on method [OK]
Hint: Use @UseGuards on method for route-level guards [OK]
Common Mistakes:
  • Putting @UseGuards only on controller for route guard
  • Confusing global providers with route guards
  • Using non-existent @GlobalGuard decorator
3. Given this code snippet, what will happen when a request hits the GET /users/profile route?
@UseGuards(GlobalGuard)
@Controller('users')
@UseGuards(ControllerGuard)
export class UserController {
  @Get('profile')
  @UseGuards(RouteGuard)
  getProfile() {
    return 'User Profile';
  }
}
medium
A. GlobalGuard, ControllerGuard, and RouteGuard all run in order.
B. Only GlobalGuard runs before the route handler.
C. Only RouteGuard runs, ignoring others.
D. ControllerGuard overrides and disables other guards.

Solution

  1. Step 1: Identify guard binding levels in code

    GlobalGuard is bound globally, ControllerGuard on the controller, and RouteGuard on the route method.
  2. Step 2: Understand guard execution order

    All guards bound at different levels run in order: global first, then controller, then route.
  3. Final Answer:

    GlobalGuard, ControllerGuard, and RouteGuard all run in order. -> Option A
  4. Quick Check:

    All guards run in binding order [OK]
Hint: All guards at different levels run in sequence [OK]
Common Mistakes:
  • Assuming only one guard runs
  • Thinking controller guard disables others
  • Believing global guard runs alone
4. You have a guard bound globally and another bound to a controller. The controller guard is not running on requests. What is the likely cause?
medium
A. The controller guard was not added to the controller with @UseGuards.
B. Controller guards cannot be used with global guards.
C. Guards must be bound only at one level, not multiple.
D. The global guard is blocking all requests before the controller guard runs.

Solution

  1. Step 1: Check guard binding syntax

    Controller guards must be explicitly added with @UseGuards on the controller class.
  2. Step 2: Understand guard coexistence

    Global and controller guards can coexist; global guards do not block controller guards from running.
  3. Final Answer:

    The controller guard was not added to the controller with @UseGuards. -> Option A
  4. Quick Check:

    Missing @UseGuards on controller = no controller guard [OK]
Hint: Always add @UseGuards to controller for controller guards [OK]
Common Mistakes:
  • Thinking global guard blocks controller guards
  • Believing guards can't be combined
  • Forgetting to decorate controller with @UseGuards
5. You want to apply a guard that blocks access to all routes except one specific route in a controller. Which approach correctly uses guard binding levels to achieve this?
hard
A. Bind the guard globally and use a route-level guard to allow the exception route.
B. Bind the guard only on the exception route to block all others.
C. Bind the guard on the controller and override it with a route-level guard that allows the exception.
D. Bind the guard globally and remove it from the exception route using @SkipGuards.

Solution

  1. Step 1: Understand guard override behavior

    Controller-level guards apply to all routes in that controller but can be overridden by route-level guards.
  2. Step 2: Apply guard to block all except one route

    Binding the guard on the controller blocks all routes; then a route-level guard on the exception route can allow access.
  3. Final Answer:

    Bind the guard on the controller and override it with a route-level guard that allows the exception. -> Option C
  4. Quick Check:

    Controller guard + route override = selective access [OK]
Hint: Use controller guard plus route guard override for exceptions [OK]
Common Mistakes:
  • Trying to remove global guards per route (not supported)
  • Binding guard only on exception route (wrong logic)
  • Assuming global guard can be skipped per route
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard