I'm studying about GraphQL and I would like to understand how GraphlQL will perform a query lie:
poc (id: $id) {
tradingName
id
products{
id
title
imageUrl
productVariants {
title
}
images{
url
}
}
}
On resolve_all_products
i will query only products for id.
e.g. select * from products where poc_id=10
On the resolve_product_variants
node i will query for all product variants with a specific product id.
e.g. select * from product_variants where product_id=X
Now imagine that I have 20 products and each of them has 2 product variants. So I will make one query to get all products (20) and then 20 more. Each of them will get all product variants (2) from a specific product.
So instead of a single join query, I will do 21 queries. Am I right? Is there anyway to prevent this?
Yes, you're right. It will be doing 21 queries. This is called N+1 query problem.
DataLoader can be used to optimise this.
First define a DataLoader
const DataLoader = require('dataloader');
const productVariantsLoader = new DataLoader((productIds) => // productIds will be an array of product ids
sql.table.query(`select * from product_variants where product_id in $productIds`)
)
Then in the resolver for productVariants
,
function productVariants(product) { // Resolver for productVariants
return productVariantsLoader.load(product.id)
}
That’s it. Now productVariants resolve might be called many times; but the passed product ids will be gathered by the DataLoader and the SQL query function will be called only once.