Spring Boot GraphQL Tutorial #23 - DataLoader (N+1 problem)

Опубликовано: 29 Октябрь 2024
на канале: Philip Starritt
12,882
116

The dreaded graphql N+1 problem gives most devs the creeps.

By default in GraphQL, a query resolver will resolve a field's nodes sequentially. When you have a list (see connection cursor video linked below) of nodes, It will resolve each node's fields sequentially. For example if you have 2 nodes with field X in the selection set. It will execute the query resolver first, then resolver for Node1 Field X followed by Node2 Field X. This is the N+1 problem.


I simulate how a small backend API latency can introduce massive latency into your graphql API. That is with dataloader neglect.


In most cases you would want to group together Field X values and batch them to the backing API. This leads to massive performance gains in reduction of network traffic and optimal database queries on the datasource.

Here we use the Java graphql dataloader (a direct port of facebook's dataloader) to solve this problem. We can easily use CompletableFutures to load the IDs and I recommend using a mapped batch dataloader. With the DataLoader creation you can customize the cache and maximum batch size with the DataLoaderOptions parameter.


Often there is not a 1:1 mapping of your batch loaded keys to the values returned.
For example, a SQL query may return fewer results than query IDs. (does not exist or duplicates).
If you would use the classic dataloader, then the values would be returned into the wrong requesting nodes and the last (Requested Ids minus responded ids) would have null values. This is because it mays 1:1 by default. Big trouble here.


To get around this, we can return a map from the dataloader function. When the map is processed by the DataLoader code, any keys that are missing in the map will be replaced with null values. The semantic that the number of DataLoader.load requests are matched with an equal number of values is kept.

The keys provided MUST be first class keys since they will be used to examine the returned map and create the list of results, with nulls filling in for missing values.





I also recommend reading this article I wrote for medium on how the DataLoader solves the N+1 Problem in Java Spring Boot: https://medium.com/evooq-engineering/...


Please check out the github graphql java dataloader docs for more detail and examples!



I had fun making this one, its one of my favorite graphql thingys :)
See you in the next video!
Cheers,
Philip

Spring Boot GraphQL Java: https://github.com/graphql-java-kicks...
GraphQL Java DataLoader: https://github.com/graphql-java/java-...
Mapped Batch DataLoader: https://github.com/graphql-java/java-...
GraphQL DataLoader from facebook: https://github.com/graphql/dataloader
GraphQL Connection Cursor Pagination Tutorial:    • Spring Boot GraphQL Tutorial #21 - Pa...