Other features¶
In the GraphQL world, there is a lot of debate about handling issues like authentication, or side-effects of operations. Should we handle things inside the business logic? Should we use a higher-order function to enhance queries and mutations with authorization logic? Or should we use schema directives? There is no single one-size-fits-all answer to these questions.
Nest helps address these issues with its cross-platform features like guards and interceptors. The philosophy is to reduce redundancy and provide tooling that helps create well-structured, readable, and consistent applications.
Overview¶
You can use standard guards, interceptors, filters and pipes in the same fashion with GraphQL as with any RESTful application. Additionally, you can easily create your own decorators by leveraging the custom decorators feature. Let's take a look at a sample GraphQL query handler.
As you can see, GraphQL works with both guards and pipes in the same way as HTTP REST handlers. Because of this, you can move your authentication logic to a guard; you can even reuse the same guard class across both a REST and GraphQL API interface. Similarly, interceptors work across both types of applications in the same way:
Execution context¶
Since GraphQL receives a different type of data in the incoming request, the execution context received by both guards and interceptors is somewhat different with GraphQL vs. REST. GraphQL resolvers have a distinct set of arguments: root
, args
, context
, and info
. Thus guards and interceptors must transform the generic ExecutionContext
to a GqlExecutionContext
. This is straightforward:
The GraphQL context object returned by GqlExecutionContext.create()
exposes a get method for each GraphQL resolver argument (e.g., getArgs()
, getContext()
, etc). Once transformed, we can easily pick out any GraphQL argument for the current request.
Exception filters¶
Nest standard exception filters are compatible with GraphQL applications as well. As with ExecutionContext
, GraphQL apps should transform the ArgumentsHost
object to a GqlArgumentsHost
object.
Hint
Both GqlExceptionFilter
and GqlArgumentsHost
are imported from the @nestjs/graphql
package.
Note that unlike the REST case, you don't use the native response
object to generate a response.
Custom decorators¶
As mentioned, the custom decorators feature works as expected with GraphQL resolvers.
Use the @User()
custom decorator as follows:
Hint
In the above example, we have assumed that the user
object is assigned to the context of your GraphQL application.
Execute enhancers at the field resolver level¶
In the GraphQL context, Nest does not run enhancers (the generic name for interceptors, guards and filters) at the field level see this issue: they only run for the top level @Query()
/@Mutation()
method. You can tell Nest to execute interceptors, guards or filters for methods annotated with @ResolveField()
by setting the fieldResolverEnhancers
option in GqlModuleOptions
. Pass it a list of 'interceptors'
, 'guards'
, and/or 'filters'
as appropriate:
Warning Enabling enhancers for field resolvers can cause performance issues when you are returning lots of records and your field resolver is executed thousands of times. For this reason, when you enable
fieldResolverEnhancers
, we advise you to skip execution of enhancers that are not strictly necessary for your field resolvers. You can do this using the following helper function: