graphql icon indicating copy to clipboard operation
graphql copied to clipboard

`__resolveType` function of a union resolver is not called when `mockEntireSchema` equals `false`.

Open EmericW opened this issue 2 years ago • 4 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

Current behavior

The repo showcases a simple schema first union and a single query to return some of these union items. When querying ResultItems you get the following error: Abstract type \"ResultItem\" must resolve to an Object type at runtime for field \"Query.items\". Either the \"ResultItem\" type should provide a \"resolveType\" function or each possible type should provide an \"isTypeOf\" function., although a union resolver is provided. The __resolveType function of the registered union resolver is not called.

Minimum reproduction code

https://github.com/EmericW/nestjs-union-resolver-issue

Steps to reproduce

  1. cd nestjs
  2. yarn
  3. yarn start:dev

At this point the server starts and works as expected.

  1. Uncommenting line 11 of app.module.ts results in the above mentioned error when querying ResultItems. https://github.com/EmericW/nestjs-union-resolver-issue/blob/321aa45600724d90abfe55c93e9bd3bbf05bcb57/nestjs/src/app.module.ts#L11

Expected behavior

When resolving a union type the __resolveType of the registered union resolver is called. Unaffected by the value of mockEntireSchema.

Package version

10.0.10

Graphql version

graphql: 16.3.0 apollo-server-express: 3.6.7 apollo-server-fastify: Not used.

NestJS version

8.4.4

Node.js version

16.10.0

In which operating systems have you tested?

  • [X] macOS
  • [ ] Windows
  • [ ] Linux

Other

  1. I also provided a working example of the same concept using just apollo-server. Showcasing that this indeed is probably a NestJS issue and not an issue with the underlying packages.

  2. When debugging this issue I also discovered that providing a resolver function to the GraphQL module directly does work. Like so:

 GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      mockEntireSchema: false,
      typePaths: ['./**/schema.graphql'],
      resolvers: {
        ResultItem: {
          __resolveType: (parent) => {
            console.log('Union resolver called');
            if ('duration' in parent) {
              return 'Movie';
            }

            if ('pages' in parent) {
              return 'Book';
            }
          },
        },
      },
    }),

EmericW avatar Apr 23 '22 18:04 EmericW

I have exactly the same issue, thought I was going crazy. Have implemented your workaround of declaring the resolver directly and it does work.

Will be watching this ticket so that I can hopefully remove the workaround soon.

marcdefaria avatar May 12 '22 14:05 marcdefaria

Boom boom I think I solved this one @EmericW. I was using your workaround until I realised that you need to include the Resolver that as a provider for a Module in order for it to work.

So in one of my Modules, I added it and it worked. See below:

@Module({
  providers: [
      SearchQueryResolver,
      SearchService,
      WorkspaceService,
      PageableResolver // Add this and all is well!
  ]})
export default class SearchModule {}

marcdefaria avatar Jun 13 '22 15:06 marcdefaria

@marcdefaria I did register the union resolver in the root module (the only module) of my reproduction case. https://github.com/EmericW/nestjs-union-resolver-issue/blob/master/nestjs/src/app.module.ts

EmericW avatar Jun 14 '22 19:06 EmericW

I also have this issue- @EmericW did you figure this out?

shadiramadan avatar Oct 04 '22 18:10 shadiramadan