11Using Dataloader
22================
33
4- If you are using ``graphql``, you are likely to making queries on a graph of data (surprise surprise). But its easy
4+ If you are using ``graphql``, you are likely to making queries on a graph of data (surprise surprise). But it's easy
55to implement inefficient code with naive loading of a graph of data.
66
77Using ``java-dataloader`` will help you to make this a more efficient process by both caching and batching requests for that graph of data items. If ``dataloader``
@@ -30,27 +30,52 @@ share many friends in common.
3030
3131.. code-block:: json
3232
33- [hero: [name: 'R2-D2', friends: [
34- [name: 'Luke Skywalker', friends: [
35- [name: 'Han Solo'], [name: 'Leia Organa'], [name: 'C-3PO'], [name: 'R2-D2']]],
36- [name: 'Han Solo', friends: [
37- [name: 'Luke Skywalker'], [name: 'Leia Organa'], [name: 'R2-D2']]],
38- [name: 'Leia Organa', friends: [
39- [name: 'Luke Skywalker'], [name: 'Han Solo'], [name: 'C-3PO'], [name: 'R2-D2']]]]]
33+ [
34+ hero: [
35+ name: 'R2-D2',
36+ friends: [
37+ [
38+ name: 'Luke Skywalker',
39+ friends: [
40+ [name: 'Han Solo'],
41+ [name: 'Leia Organa'],
42+ [name: 'C-3PO'],
43+ [name: 'R2-D2']
44+ ]
45+ ],
46+ [
47+ name: 'Han Solo',
48+ friends: [
49+ [name: 'Luke Skywalker'],
50+ [name: 'Leia Organa'],
51+ [name: 'R2-D2']
52+ ]
53+ ],
54+ [
55+ name: 'Leia Organa',
56+ friends: [
57+ [name: 'Luke Skywalker'],
58+ [name: 'Han Solo'],
59+ [name: 'C-3PO'],
60+ [name: 'R2-D2']
61+ ]
62+ ]
63+ ]
64+ ]
4065 ]
4166
42- A naive implementation would called a `DataFetcher` to retrieved a person object every time it was invoked.
67+ A naive implementation would call a `DataFetcher` to retrieve a person object every time it was invoked.
4368
4469In this case it would be *15* calls over the network. Even though the group of people have a lot of common friends.
4570With `dataloader` you can make the `graphql` query much more efficient.
4671
47- As `graphql` descends each level of the query ( eg as it processes `hero` and then `friends` and then for each their `friends`),
72+ As `graphql` descends each level of the query (e.g. as it processes `hero` and then `friends` and then for each their `friends`),
4873the data loader is called to "promise" to deliver a person object. At each level `dataloader.dispatch()` will be
4974called to fire off the batch requests for that part of the query. With caching turned on (the default) then
50- any previously returned person will be returned as is for no cost.
75+ any previously returned person will be returned as- is for no cost.
5176
52- In the above example there are only *5* unique people mentioned but with caching and batching retrieval in place their will be only
53- *3* calls to the batch loader function. *3* calls over the network or to a database is much better than *15* calls you will agree.
77+ In the above example there are only *5* unique people mentioned but with caching and batching retrieval in place there will be only
78+ *3* calls to the batch loader function. *3* calls over the network or to a database is much better than *15* calls, you will agree.
5479
5580If you use capabilities like `java.util.concurrent.CompletableFuture.supplyAsync()` then you can make it even more efficient by making the
5681the remote calls asynchronous to the rest of the query. This will make it even more timely since multiple calls can happen at once
@@ -118,7 +143,7 @@ Here is how you might put this in place:
118143 GraphQL graphQL = GraphQL.newGraphQL(buildSchema())
119144 .instrumentation(dispatcherInstrumentation)
120145 .build();
121- ```
146+
122147
123148One thing to note is the above only works if you use `DataLoaderDispatcherInstrumentation` which makes sure `dataLoader.dispatch()`
124149is called. If this was not in place, then all the promises to data will never be dispatched ot the batch loader function
@@ -137,7 +162,7 @@ If your data can be shared across web requests then you might want to scope your
137162longer than the web request say.
138163
139164But if you are doing per request data loaders then creating a new set of ``GraphQL`` and ``DataLoader`` objects per
140- request is super cheap. Its the ``GraphQLSchema`` creation that can be expensive, especially if you are using graphql SDL parsing.
165+ request is super cheap. It's the ``GraphQLSchema`` creation that can be expensive, especially if you are using graphql SDL parsing.
141166
142167Structure your code so that the schema is statically held, perhaps in a static variable or in a singleton IoC component but
143168build out a new ``GraphQL`` set of objects on each request.
0 commit comments