Why does async code mess up my dataloader in a graphql resolver?

100 views Asked by At

I have a dataloader that I'm using to batch requests to a service to get my user's addresses. The loader doesn't batch requests correctly when the parent resolver uses async code. Here's a general idea of what my code looks like:

// User.ts 
import Demographic from './Demographic'

export type User { 
 name: 'User', 
 description: 'User',
 ...
 fields: () => {
  someField: ...
  demographicInformation: {
     type: Demographic,
     resolve: async (source, args, context) => {
      // removing the following line causes the loader in Demographics.ts to batch properly
      const [hasViewPermissions, hasAuthForDemographics] = await Promise.all([getViewPermissions(), getAuthForDemographics()])
      if (hasAuth && hasAuthForDemographics){ return source}
      else { return null } 
     
     }

 } 

}
...
//Demographics.ts
export type Demographics { 
 name: 'somename', 
 description: '',
 fields: {
    name: // ...
    address: {
     type: Address, 
     resolve:  async (source, args, context) => {
       return myloaders.addressloader.load(myid)
     }

   }
}

I'm aware that the dataloader docs say that "DataLoader will coalesce all individual loads which occur within a single frame of execution (a single tick of the event loop)", however I don't fully understand why using an async/await messes that up if that's done in the parent resolver (User in my case). And, I need to have the parent check the auth using some form of async code, is there a way to still make these auth calls at the parent level and also use the dataloader effectively?

I've seen this issue noted in Github as well, but I don't think any workaround (such as adding the async calls to the loader) will work for me.

0

There are 0 answers