graphqlnestjsmercurius

how to implement graphql-query-complexity on nestjs with mercurius


I'm trying to implement maximum complexity for queries on a graphql API. Although, NestJs doesn't have documentation on how to do that with mercurius (only apollo).

https://docs.nestjs.com/graphql/complexity

I've tried following this guide, but then I've got an error:

this.includeDirectiveDef = this.context.getSchema().getDirective('include');
TypeError: Cannot read properties of undefined (reading 'getDirective')

my code:

plugins: [
  {
    plugin: createComplexityRule({
      maximumComplexity: 2,
      variables: {},
      context: {},
      onComplete: (complexity: number) => {
        console.log('Determined query complexity: ', complexity);
      },
      createError: (max: number, actual: number) => {
        return new GraphQLError(
          `Query is too complex: ${actual}. Maximum allowed complexity: ${max}`,
        );
      },
      estimators: [
        simpleEstimator({
          defaultComplexity: 1,
        }),
      ],
    }),
    options: {},
  },
]

Solution

  • Mercurius is capable of complexity limiting by using validation rules, if cache is disabled.

    The code for integrating with NestJS should be as follows:

    import { ConfigModule, ConfigService } from '@nestjs/config';
    import { GraphQLModule } from '@nestjs/graphql';
    import { MercuriusDriver, MercuriusDriverConfig } from '@nestjs/mercurius';
    import queryComplexity, { simpleEstimator } from 'graphql-query-complexity';
    
    export const GraphQLProvider =
      GraphQLModule.forRootAsync<MercuriusDriverConfig>({
        driver: MercuriusDriver,
        imports: [ConfigModule],
        inject: [ConfigService],
        useFactory: async (configService: ConfigService) => {
          return {
            cache: false,
            validationRules: ({ variables, operationName }) => [
              queryComplexity({
                maximumComplexity: 1,
                variables,
                operationName,
                estimators: [simpleEstimator({ defaultComplexity: 1 })],
                onComplete: () => {},
              }),
            ],
          };
        },
      });
    
    

    For more information, read the docs: https://github.com/slicknode/graphql-query-complexity