mercurius-js / mercurius

Implement GraphQL servers and gateways with Fastify
https://mercurius.dev/
MIT License
2.34k stars 234 forks source link

Dataloader function is not called for __resolveReference #902

Closed sushilkjaiswar closed 1 year ago

sushilkjaiswar commented 1 year ago

Anyone encountered issues with resolveRefrence's dataloader implmentation where the dataloader for `resolverRefrence` is never called even after loader is registered by mercurius.

I am using Mercurius + Federation + Nestjs and getLoaders function looks like this,


//Resolver
  @ResolveReference()
  public resolveReference(reference: IReference): Promise<User> {
         return; 
  }

// Get Loaders
 public getLoaders() {
    return {
      User: {
        __resolveReference: this.loadUsersReferences(),
      },
    };
  }

Looking at the mercurius source code I figured type.resolveReference is assigned the loader function but unable to figure where is this called in the source code.


for (const prop of Object.keys(resolver)) { 
 if (subscriptionsActive && name === subscriptionTypeName) {

            fields[prop] = {

              ...fields[prop],

              ...resolver[prop]

            }
          } else if (prop === '__resolveReference') {

            type.resolveReference = resolver[prop]

          } else if (fields[prop]) {

            fields[prop].resolve = resolver[prop]

          } else {

            throw new MER_ERR_INVALID_OPTS('Cannot find field ${prop} of type ${type}')

          }
        }

Graphql v16.6.0 Mercurius v11.2.0 Nestjs v9.0.0

mcollina commented 1 year ago

Thanks for reporting. We do not have the resources to support Nest.js users. Please refer to the Nest Discord channel (support) for such questions.

Can you provide steps to reproduce without Nest.js? We often need a reproducible example, e.g. some code that allows someone else to recreate your problem by just copying and pasting it. If it involves more than a couple of different file, create a new repository on GitHub and add a link to that.

sushilkjaiswar commented 1 year ago

I have posted on discord channel it self but I raised issues here because while debugging I found that other data loaders function are called except __resolveReference, what I mean by this, example below

// Get Loaders
 public getLoaders() {
    return {
      User: {
        __resolveReference: this.loadUsersReferences(),
        posts: this.loadPosts()
      },
    };
  }

In the above example posts data loader will be called without any issues in mercurius lib but __resolveRefrence is never called. I will try to check and get an example in plain mercurius to see if it works or has the same issue.

sushilkjaiswar commented 1 year ago

@mcollina Can you point me where exactly mercurius calls resolveReference function after it assigns the function from loader. I want to try some debugging.

mcollina commented 1 year ago

What are you using as gateway? My understanding about Apollo Gateway was that it resolves each reference individually. If you use Mercurius you shouldn't have this issue.

There is no special logic for __resolveReference. It's just a normal resolver.

sushilkjaiswar commented 1 year ago

I am using mercurius gateway, the code is below

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusGatewayDriverConfig>({
      driver: MercuriusGatewayDriver,
      graphiql: true,
      federationMetadata: true,
      allowBatchedQueries: true,
      gateway: {
        services: [
          { name: 'post', url: 'http://localhost:3003/graphql' },
          { name: 'user', url: 'http://localhost:3002/graphql' },
        ],
        pollingInterval: 2000,
      },
    }),
  ],
})
export class AppModule {}

When I went through mercurius codebase I found that __resolveRefrence is assigned to type.resolveReference = resolver[prop] whereas other fields have fields[prop].resolve = resolver[prop]. So my query was where in the code resolveReference is called?

anapaulalemos commented 1 year ago

Hey @sushilkjaiswar are you still facing this issue? I've tried to reproduced it locally (without Nest.js) and everything seems to be working as expected. If you're still having this issue, could you please provide a reproducible example or steps to reproduce it?