Bird
Raised Fist0
NestJSframework~8 mins

Protected routes with guards in NestJS - Performance & Optimization

Choose your learning style10 modes available
Performance: Protected routes with guards
MEDIUM IMPACT
This concept affects the server response time and initial page load speed by adding authorization checks before route handlers execute.
Protecting routes to restrict access to authorized users
NestJS
import { CanActivate, ExecutionContext, Injectable, UseGuards, Controller, Get } from '@nestjs/common';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const request = context.switchToHttp().getRequest();
    return !!request.user;
  }
}

@Controller()
export class ProfileController {
  @UseGuards(AuthGuard)
  @Get('/profile')
  getProfile() {
    // handle profile
  }
}
Separates authorization logic into reusable guards, reducing duplication and improving maintainability.
📈 Performance GainSingle authorization check per request before route handler, reducing redundant processing.
Protecting routes to restrict access to authorized users
NestJS
app.get('/profile', (req, res) => {
  if (!req.user) {
    res.status(401).send('Unauthorized');
    return;
  }
  // handle profile
});
Authorization logic is mixed inside route handlers causing repeated checks and harder maintenance.
📉 Performance CostAdds redundant checks on every request, increasing server processing time slightly.
Performance Comparison
PatternServer ProcessingAuthorization ChecksResponse DelayVerdict
Inline auth checks in routesRepeated per routeMultiple redundant checksHigher delay per request[X] Bad
Centralized guardsSingle reusable checkOne check per requestMinimal added delay[OK] Good
Rendering Pipeline
When a request hits a protected route, the guard runs first to check authorization before the route handler executes. If unauthorized, the response is sent early, preventing unnecessary processing.
→Server Request Handling
→Middleware Execution
→Route Handler Execution
⚠️ BottleneckAuthorization check in guard adds slight delay before route handler
Core Web Vital Affected
LCP
This concept affects the server response time and initial page load speed by adding authorization checks before route handlers execute.
Optimization Tips
1Use guards to centralize authorization logic for better performance and maintainability.
2Keep guard logic simple and synchronous to minimize response delay.
3Avoid duplicating authorization checks inside route handlers.
Performance Quiz - 3 Questions
Test your performance knowledge
What is the main performance impact of using guards for protected routes in NestJS?
AThey reduce the number of HTTP requests from the client.
BThey increase the size of the client-side bundle.
CThey add a small processing step before route handlers, slightly increasing response time.
DThey eliminate the need for server-side authorization.
DevTools: Network
How to check: Open DevTools, go to Network tab, reload protected route, and inspect response time and headers.
What to look for: Look for increased server response time if guards are complex; minimal delay indicates efficient guard usage.

Practice

(1/5)
1. What is the main purpose of a guard in NestJS when protecting routes?
easy
A. To decide if a request can access a route based on custom logic
B. To format the response data before sending it
C. To handle database connections automatically
D. To log every request made to the server

Solution

  1. Step 1: Understand the role of guards

    Guards in NestJS are designed to control access to routes by running custom logic before the route handler executes.
  2. Step 2: Identify the correct purpose

    Among the options, only deciding if a request can access a route matches the guard's role.
  3. Final Answer:

    To decide if a request can access a route based on custom logic -> Option A
  4. Quick Check:

    Guards control access = C [OK]
Hint: Guards allow or block access before route runs [OK]
Common Mistakes:
  • Confusing guards with interceptors or middleware
  • Thinking guards modify response data
  • Assuming guards handle database tasks
2. Which of the following is the correct way to apply a guard to a route in NestJS?
easy
A. @UseGuards(AuthGuard) before the controller class
B. @UseGuards(AuthGuard) before the route handler method
C. @ApplyGuard(AuthGuard) inside the constructor
D. @Guard(AuthGuard) before the route handler

Solution

  1. Step 1: Recall the decorator for guards

    The correct decorator to apply guards in NestJS is @UseGuards().
  2. Step 2: Identify correct placement

    This decorator can be placed before a route handler method or a controller class. @UseGuards(AuthGuard) before the route handler method correctly shows it before a route handler method.
  3. Final Answer:

    @UseGuards(AuthGuard) before the route handler method -> Option B
  4. Quick Check:

    @UseGuards + route method = D [OK]
Hint: Use @UseGuards() decorator on methods or controllers [OK]
Common Mistakes:
  • Using @Guard or @ApplyGuard which don't exist
  • Placing decorators inside constructor
  • Confusing middleware with guards
3. Given this guard implementation, what will happen when a request is made?
import { CanActivate, ExecutionContext } from '@nestjs/common';

export class AlwaysDenyGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    return false;
  }
}

Applied to a route, what is the result?

medium
A. The guard throws an error causing a server crash
B. The route handler runs and returns its response
C. The request is blocked and the route handler does not run
D. The guard logs the request but allows it

Solution

  1. Step 1: Analyze the canActivate method

    The guard's canActivate method always returns false, meaning it denies access.
  2. Step 2: Understand guard effect on route

    When canActivate returns false, NestJS blocks the request and does not run the route handler.
  3. Final Answer:

    The request is blocked and the route handler does not run -> Option C
  4. Quick Check:

    canActivate false blocks request = A [OK]
Hint: canActivate false means block access [OK]
Common Mistakes:
  • Thinking false lets the route run
  • Assuming guard throws error on false
  • Confusing logging with blocking
4. Identify the error in this guard code snippet:
import { CanActivate, ExecutionContext } from '@nestjs/common';

export class MyGuard implements CanActivate {
  canActivate(context: ExecutionContext) {
    if (context.switchToHttp().getRequest().user) {
      return true;
    }
  }
}
medium
A. Incorrect import of ExecutionContext
B. Using switchToHttp() is not allowed in guards
C. canActivate should be async but is not
D. Missing return statement when user is not present

Solution

  1. Step 1: Check canActivate return paths

    The method returns true if user exists, but returns nothing (undefined) otherwise.
  2. Step 2: Understand guard return requirements

    canActivate must always return a boolean or Promise<boolean>. Missing return means undefined, which is invalid.
  3. Final Answer:

    Missing return statement when user is not present -> Option D
  4. Quick Check:

    All paths must return boolean = B [OK]
Hint: Always return true or false in canActivate [OK]
Common Mistakes:
  • Forgetting else return false
  • Assuming undefined is false
  • Thinking async is always required
5. You want to protect a route so only users with role 'admin' can access it. Which guard implementation correctly enforces this?
import { CanActivate, ExecutionContext } from '@nestjs/common';

export class RolesGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    // Which condition correctly checks for admin role?
  }
}
hard
A. return user && user.role === 'admin';
B. return user && user.roles.includes('admin');
C. return user && user.roles === 'admin';
D. return user && user.role.includes('admin');

Solution

  1. Step 1: Understand user role structure

    Assuming user has a single role string in property role, not an array.
  2. Step 2: Check each condition

    return user && user.role === 'admin'; correctly compares user.role === 'admin'. return user && user.roles.includes('admin'); assumes roles is an array, which may be incorrect. Options C and D misuse property types.
  3. Final Answer:

    return user && user.role === 'admin'; -> Option A
  4. Quick Check:

    Check user.role string equals 'admin' = A [OK]
Hint: Match exact role property type to check admin [OK]
Common Mistakes:
  • Confusing roles array with single role string
  • Using includes on a string property
  • Checking wrong property name
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