paint-brush
The Easiest Way to Solve N+1 Problem on GraphQLby@howardJohn
2,013 reads
2,013 reads

The Easiest Way to Solve N+1 Problem on GraphQL

by HowardSeptember 22nd, 2020
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

The Easiest Way to Solve N+1 Problem on GraphQL is solving N-1 problem. Use this package https://github.com/oney/sequelize-proxy to solve this problem. It creates built-in dataloaders to collect hasOne, belongsTo, hasMany relation query with where, order, etc. You don’t have to deal with any of these by yourself. The disadvantage of this method is we have to declare a data loader for each model in our ORM.
featured image - The Easiest Way to Solve N+1 Problem on GraphQL
Howard HackerNoon profile picture

GraphQL is awesome! But one of the most annoying parts to implement a GraphQL server is solving N+1 problem.

TL;DR

Use this package https://github.com/oney/sequelize-proxy

Dive in

In general, there are two methods to solve N+1 problem.

First method:

Parsing info: GraphQLResolveInfo in query/mutation levels to determine what data the whole operation needs and pre-fetch all data in one single SQL query.

This is how join-monsterpostgraphile, and prisma do it.

One inconvenience of this method(join-monster facing) is you have to declare dependencies of fields to make pre-fetching know how to construct the one single query.

Another inconvenience of this method(postgraphileprisma facing) is the whole GraphQL type schema are predetermined and bound to your database schema. You can’t change your GraphQL schema.

Second method:

Make SQL queries in any deeper resolvers, but use something like dataloader to collect all queries and combine them to single one. This method is more free comparing to first method because you don’t have to declare any dependency and bind to database schema.

The disadvantage of this method is we have to declare a data loader for each model in our ORM (Even though you can write some function to wrap this functionality). Besides, dataloader way can easily solve belongsTo relation but are hard to solve hasMany relation. When querying hasMany relation with where and order, it will be more complex for dataloaders to collect queries from different resolvers and make one SQL query.

Solution

So, use this package https://github.com/oney/sequelize-proxy

It creates built-in dataloaders to collect hasOne, belongsTo, hasMany, belongsToMany relation query with where, order, etc. and make a single SQL query to optimize. You don’t have to deal with any of these by yourself.

If you have any questions, let me know in Community. Any suggestions are also welcome!