All quizzesHard
Dynamic Modules — Series 2
Preview — 3 of 10 questions
At what point in the request lifecycle does a Guard run, and what happens if canActivate returns false?
javascript
@Injectable()
export class RolesGuard implements CanActivate {
canActivate(context: ExecutionContext): boolean {
const request = context.switchToHttp().getRequest();
return request.user?.role === 'admin';
}
}
@UseGuards(RolesGuard)
@Get('admin-only')
adminRoute() { return 'secret'; }AGuards run after the route handler executes, to validate its response before sending it to the client
BGuards only run in development mode and are automatically skipped in production for performance
CReturning false from canActivate causes Nest to silently retry the request in an infinite loop until it returns true
DGuards run before the route handler (and before any Pipes), specifically to determine whether the request is authorized to proceed at all; if canActivate returns false (or throws), Nest immediately halts the request and returns a 403 Forbidden response, without ever invoking the route handler
What does calling next.handle() represent, and why does the interceptor wrap it with .pipe(map(...))?
javascript
@Injectable()
export class TransformInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
return next.handle().pipe(map(data => ({ success: true, data })));
}
}Anext.handle() invokes the actual route handler and returns an Observable of its result; interceptors can transform that result — before it's sent to the client — by piping RxJS operators (like map) onto that Observable, here wrapping the raw handler output in a consistent { success, data } envelope
Bnext.handle() synchronously returns the route handler's return value as a plain object; .pipe() here is an unrelated Node.js stream API, with no connection to the HTTP response
Cnext.handle() must always be called exactly twice inside every interceptor — once before and once after the route handler
DInterceptors cannot access or transform the response at all — they can only modify the incoming request before it reaches the handler
What's the role of a Pipe here, and when does it run relative to Guards?
javascript
@Injectable()
export class ParseIntPipe implements PipeTransform {
transform(value: string, metadata: ArgumentMetadata): number {
const val = parseInt(value, 10);
if (isNaN(val)) throw new BadRequestException('Validation failed: not a number');
return val;
}
}
@Get(':id')
findOne(@Param('id', ParseIntPipe) id: number) { /* ... */ }APipes run before Guards, to pre-validate the raw request body before authorization is even checked
BPipes transform and/or validate incoming arguments before they reach the route handler — here, converting a string route param into a number, or throwing a 400 error if it's invalid. Pipes run after Guards (and after an Interceptor's pre-handler phase) but before the route handler itself executes — ensuring the handler only ever receives already-validated, correctly-typed data
CPipes can only validate request bodies — they have no way to operate on route params or query strings
DPipes replace the need for Guards entirely; authorization logic should always live in a custom Pipe instead
Sign up free to play
Answer all 10 questions (7 more), see explanations for every answer, and track your score.