nestjs / nest

A progressive Node.js framework for building efficient, scalable, and enterprise-grade server-side applications with TypeScript/JavaScript 🚀
https://nestjs.com
MIT License
67.06k stars 7.56k forks source link

`autoSchemaFile` breaks opentelemetry auto instrumentation for `resolve` spans #14049

Open bmbferreira opened 1 day ago

bmbferreira commented 1 day ago

Is there an existing issue for this?

Current behavior

Currently if autoSchemaFile is set and if the schema is passed as well in the configs for the factory, only the resolvers set using decorators and TypeScript classes to generate the corresponding GraphQL schema are instrumented. This happens because the wrapper functions from the autoinstrumentation library are executed before the merge of the schemas.

Example:


const schemaPath = require.resolve('@X/graphql').replace('index.ts', 'schema')

// eslint-disable-next-line security/detect-non-literal-fs-filename
const files = fs.readdirSync(schemaPath)
const typePaths = files.map((file) => `${schemaPath}/${file}`)
const loadedTypePaths = loadFilesSync(typePaths)
const typeDefs = mergeTypeDefs(loadedTypePaths)

let schema = makeExecutableSchema({ typeDefs, resolvers })
schema = requiresAuthenticationDirective(schema)
schema = rateLimitDirectiveTransformer(schema)
schema = lexicographicSortSchema(schema)

@Module({
  imports: [
    GraphQLModule.forRootAsync<ApolloDriverConfig>({
      driver: ApolloDriver,
      useFactory: () => ({
        path: '/',
        schema,
        autoSchemaFile: true,
        formatError: graphqlErrorHandler,
        context: getContext,
        playground: false,
        /**
         * Introspection is enabled by default and protected for super-admins
         * only using a plugin.
         */
        introspection: true,
        plugins,
        subscriptions: {
          'graphql-ws': {
            path: '/subscriptions',
          },
        },
      }),
    }),
    NestModule,
    ControllersModule,
  ],
})

The resolvers I have set on the schema only work when I remove the autoSchemaFile config.

Minimum reproduction code

https://github.com/nestjs/nest/blob/master/sample/23-graphql-code-first/package.json

Steps to reproduce

  1. Pick this example: https://github.com/nestjs/nest/tree/master/sample/23-graphql-code-first
  2. Add opentelemetry auto instrumentation library for graphql
  3. Add a custom gql file with more resolvers besides the resolver configured using decorators: https://github.com/nestjs/nest/blob/master/sample/23-graphql-code-first/src/recipes/models/recipe.model.ts
  4. Notice that only the resolvers using the decorator are instrumented and no spans show up for other resolvers set on the gql file, unless the autoSchemaFile config is removed.

Expected behavior

The instrumentation should only be invoked after the merge of the two schemas so all the resolve spans can be created.

Package

Other package

@nestjs/graphql

NestJS version

10.3.10

Packages versions

@nestjs/graphql@npm:12.2.0

Node.js version

22.9.0

In which operating systems have you tested?

Other

No response

Kelvin-ui-hub commented 19 hours ago

Hey is the issue fixed?

kamilmysliwiec commented 3 hours ago

Not sure if i'm following. Why do you use autoSchemaFile in combination with your own pre-created schema? autoSchemaFile isn't designed to work this way - if you have your own gql files you should rather use the "schema-first" approach instead