You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Guards in NestJS are used as a guarding mechanism on API routes. For GraphQL a global guard will work on all resolvers or when used with the UseGuard decorator on a specific field resolver or on a specific resolver for all field resolvers.
The problem
When listing multiple entities and their nested entities, e.g.
{
users {
profile {
id
}
}
}
the guard will be executed before each execution of the field resolver (quick maths: 300 users = 300 guard executions).
Furthermore, the guard in most cases is not used to protect resolvers but rather to switch context or attach the user to the context (300 times in the previous example) which a simple interceptor should be able to do ONCE.
The problem deepens when dataloaders are involved.
The fundamental nature of the dataloader is to coalesce all individual loads that occur within a single frame of execution (a single tick of the event loop). When a guard is introduced in the equation its execution is not able to fit in the same tick, so for each resolver + guard an addition tick is introduced, forcing the dataloader to batch a single entry per tick which makes it useless.
Acceptance criteria
The UseGuard decorator is removed for resolvers without the AuthorizationAgentPrivilege decorator
A global interceptor is introduced, doing the job of the previously used GraphqlGuard
Additional Context
Having UseGuard without the AuthorizationAgentPrivilege decorator is useless since no privilege is attached that the guard requires to execute any actual guarding (see GraphqlGuard.handleRequest for reference)
The text was updated successfully, but these errors were encountered:
The scene
Guards in NestJS are used as a guarding mechanism on API routes. For GraphQL a global guard will work on all resolvers or when used with the
UseGuard
decorator on a specific field resolver or on a specific resolver for all field resolvers.The problem
When listing multiple entities and their nested entities, e.g.
the guard will be executed before each execution of the field resolver (quick maths: 300 users = 300 guard executions).
Furthermore, the guard in most cases is not used to protect resolvers but rather to switch context or attach the user to the context (300 times in the previous example) which a simple interceptor should be able to do ONCE.
The problem deepens when dataloaders are involved.
The fundamental nature of the dataloader is to coalesce all individual loads that occur within a single frame of execution (a single tick of the event loop). When a guard is introduced in the equation its execution is not able to fit in the same tick, so for each resolver + guard an addition tick is introduced, forcing the dataloader to batch a single entry per tick which makes it useless.
Acceptance criteria
UseGuard
decorator is removed for resolvers without theAuthorizationAgentPrivilege
decoratorGraphqlGuard
Additional Context
Having
UseGuard
without theAuthorizationAgentPrivilege
decorator is useless since no privilege is attached that the guard requires to execute any actual guarding (seeGraphqlGuard.handleRequest
for reference)The text was updated successfully, but these errors were encountered: