Skip to content

NestJS Execution Context

Guards, interceptors, and exception filters all receive an ExecutionContext object. This lesson explains what it represents and how it provides a platform-agnostic view of the current request.

What Is ExecutionContext?

ExecutionContext extends Nest's simpler ArgumentsHost with additional methods for inspecting the current handler and its class, letting the same guard or interceptor work correctly whether it's applied to an HTTP route, a WebSocket event, or a microservice message pattern.

canActivate(context: ExecutionContext): boolean {
  const request = context.switchToHttp().getRequest();
  const handler = context.getHandler();  // the route method itself
  const controllerClass = context.getClass(); // the controller class
  return true;
}

switchToHttp() narrows the generic context to an HTTP-specific one, exposing getRequest() and getResponse(). Equivalent methods exist for WebSockets (switchToWs()) and RPC/microservices (switchToRpc()).

Key ExecutionContext Methods

context.switchToHttp().getRequest()
context.switchToHttp().getResponse()
context.switchToWs().getClient()
context.switchToRpc().getData()
context.getHandler()
context.getClass()
  • switchToHttp(), switchToWs(), and switchToRpc() adapt the context to a specific transport.
  • getHandler() returns the actual method reference, useful with Reflector to read metadata.
  • getClass() returns the controller class, for class-level metadata.
  • ArgumentsHost is the more limited base interface used inside exception filters.

ExecutionContext Cheatsheet

The context object shared by guards, interceptors, and filters.

Method Returns
switchToHttp() HTTP-specific context with getRequest()/getResponse()
switchToWs() WebSocket-specific context
switchToRpc() Microservice/RPC-specific context
getHandler() Reference to the matched route handler method
getClass() Reference to the matched controller class

Why This Abstraction Matters

Without ExecutionContext, a guard written for HTTP routes would need entirely different code to work with WebSocket gateways or microservice controllers. Because Nest normalizes all of these behind one interface, the same RolesGuard you wrote for REST routes can often be reused unchanged for WebSocket events.

Reading Metadata Through the Context

Combining context.getHandler() and context.getClass() with Reflector.getAllAndOverride() is the standard pattern for reading custom decorator metadata (like @Roles() or @Public()) from inside a guard or interceptor.

Common Mistakes

  • Calling switchToHttp() inside a guard meant to also support WebSocket or microservice contexts.
  • Manually branching on transport type instead of using the appropriate switchTo*() method.
  • Forgetting that getHandler() returns the method reference, not its name as a string.
  • Confusing ExecutionContext with the more limited ArgumentsHost used inside exception filters.

Key Takeaways

  • ExecutionContext gives guards, interceptors, and filters a transport-agnostic view of the current request.
  • switchToHttp(), switchToWs(), and switchToRpc() adapt the context to a specific transport.
  • getHandler() and getClass() are the standard way to read custom decorator metadata.
  • This abstraction is what lets the same guard or interceptor work across HTTP, WebSockets, and microservices.

Pro Tip

When writing a reusable guard or interceptor meant to work across transports, always go through context.switchToHttp() (or the matching method) rather than assuming the request object's shape, it's what makes the same class portable to WebSocket gateways later without a rewrite.