Typegraphql add FieldResolver for an array of object

117 views Asked by At

Here is my problem : I have a type Cart defined like this :

@ObjectType()
export class Cart {
    @Field(() => ID)
    id: string;

    @Field((_type) => String)
    ownerId: String

    @Field((_type) => User)
    owner: User;
}

And I resolve the owner of the cart with a type resolver :

@FieldResolver((_type) => User)
async owner(@Root() cart: Cart): Promise<User> {
    return (await UserModel.findById(cart.ownerId))!
}

But, when I do a query for multiple carts, the FieldResolver will be called once for each cart. Which is inefficient. Id'like to be able to be able to take all the carts id, and find all the owners in one query.

Is there a way to achieve this ?

Thanks

1

There are 1 answers

0
Oreste Viron On BEST ANSWER

The solution was to use the graphql dataloader project : https://github.com/graphql/dataloader

Must define a dataloader in the application context. Something like :

{
  context: async ({req, res}) => {
    return {
      userDataLoader: new DataLoader(async (ids) => {
        return UserModel.find({
            _id: {
                $in: ids
            }
        })
      })
    }
  }
}

And in the resolver :

@FieldResolver((_type) => User)
async owner(@Root() cart: CartProjection, @Ctx() context: Context,) {
   return context.userDataLoader.load(cart.ownerId)
}

The users are effectivelly loaded once magically.