Search code examples
graphqlgraphql-js

GraphQL - Overloading database?


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?


Solution

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