Skip to content

Commit f558c4b

Browse files
authored
Merge pull request #196 from graphql-java/chained-dataloaders
Add documentation for Chained DataLoaders
2 parents f9d6eec + 42627e5 commit f558c4b

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed

documentation/batching.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,3 +370,67 @@ DataFetcher<?> dataFetcherThatCallsTheDataLoader = new DataFetcher<Object>() {
370370
}
371371
};
372372
```
373+
374+
## Chained DataLoaders
375+
376+
The automatic dispatching of Chained DataLoaders is a new feature included in GraphQL Java 25.0 onwards. Before this version, DataLoaders in chains needed to be manually dispatched.
377+
378+
A Chained DataLoader is where one DataLoader depends on another, within the same DataFetcher.
379+
380+
For example in code:
381+
```java
382+
DataFetcher<CompletableFuture<Object>> df1 = env -> {
383+
return env.getDataLoader("name").load("Key1").thenCompose(result -> {
384+
return env.getDataLoader("email").load(result);
385+
});
386+
};
387+
```
388+
389+
### How do I enable Chained DataLoaders?
390+
You must opt-in to Chained DataLoaders via `GraphQLUnusualConfiguration.DataloaderConfig`, as this may change order of dispatching.
391+
392+
Set `enableDataLoaderChaining(true)` to enable Chained DataLoaders.
393+
394+
For example, to set `enableDataLoaderChaining`:
395+
```java
396+
GraphQL graphQL = GraphQL.unusualConfiguration(graphqlContext)
397+
.dataloaderConfig()
398+
.enableDataLoaderChaining(true);
399+
```
400+
401+
### What changed in GraphQL Java 25.0?
402+
The DataFetcher in the example above, before version 25.0 would have caused execution to hang, because the second DataLoader ("email") was never dispatched.
403+
404+
Prior to version 25.0, users of GraphQL Java needed to manually dispatch DataLoaders to ensure execution completed. From version 25.0, the GraphQL Java engine will automatically dispatch Chained DataLoaders.
405+
406+
If you're looking for more examples, and the technical details, please see [our tests](https://github.com/graphql-java/graphql-java/blob/master/src/test/groovy/graphql/ChainedDataLoaderTest.groovy).
407+
408+
Note: The GraphQL Java engine can only optimally calculate DataLoader dispatches on a per-level basis. It does not calculate optimal DataLoader dispatching across different levels of an operation's field tree.
409+
410+
### A special case: Delayed DataLoaders
411+
412+
In a previous code snippet, we demonstrated one DataLoader depending on another DataLoader.
413+
414+
Another special case is a "delayed" DataLoader, where a DataLoader depends on a slow async task instead. For example, here are two DataFetchers from [a test example](https://github.com/graphql-java/graphql-java/blob/master/src/test/groovy/graphql/ChainedDataLoaderTest.groovy):
415+
416+
```groovy
417+
def fooDF = { env ->
418+
return supplyAsync {
419+
Thread.sleep(1000)
420+
return "fooFirstValue"
421+
}.thenCompose {
422+
return env.getDataLoader("dl").load(it)
423+
}
424+
} as DataFetcher
425+
426+
def barDF = { env ->
427+
return supplyAsync {
428+
Thread.sleep(1000)
429+
return "barFirstValue"
430+
}.thenCompose {
431+
return env.getDataLoader("dl").load(it)
432+
}
433+
} as DataFetcher
434+
```
435+
436+
By opting in to Chained DataLoaders, GraphQL Java will also calculate when to dispatch "delayed" DataLoaders. These "delayed" DataLoaders will be enqueued for dispatch after the async task completes.

0 commit comments

Comments
 (0)