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
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.