1 | # http-link-dataloader
|
2 |
|
3 | [![CircleCI](https://circleci.com/gh/graphcool/http-link-dataloader.svg?style=shield)](https://circleci.com/gh/graphcool/http-link-dataloader) [![npm version](https://badge.fury.io/js/http-link-dataloader.svg)](https://badge.fury.io/js/http-link-dataloader)
|
4 |
|
5 | 📚📡 HTTP Apollo Link with batching & caching provided by dataloader.
|
6 |
|
7 | ## Idea
|
8 |
|
9 | A Apollo Link that batches requests both in Node and the Browser.
|
10 | You may ask what's the difference to [apollo-link-batch-http](https://github.com/apollographql/apollo-link/tree/master/packages/apollo-link-batch-http).
|
11 | Instead of having a time-frame/fixed cache size based batching approach like in `apollo-link-batch-http`, this library uses [dataloader](https://github.com/facebook/dataloader) for batching requests. It is a more generic approach just depending on the Node.JS event loop that batches all consecutive queries directly.
|
12 | The main use-case for this library is the usage from a [`graphql-yoga`](https://github.com/graphcool/graphql-yoga) server using [`prisma-binding`](https://github.com/graphcool/prisma-binding), but it can be used in any environment, even the browser as the latest `dataloader` version also runs in browser environments.
|
13 |
|
14 | ## Usage
|
15 |
|
16 | ```ts
|
17 | import { HTTPLinkDataloader } from 'http-link-dataloader'
|
18 |
|
19 | const link = new HTTPLinkDataloader()
|
20 |
|
21 | const token = 'Auth Token'
|
22 |
|
23 | const httpLink = new HTTPLinkDataloader({
|
24 | uri: `api endpoint`,
|
25 | headers: { Authorization: `Bearer ${token}` },
|
26 | })
|
27 | ```
|
28 |
|
29 | ## Caching behavior
|
30 |
|
31 | Note that the dataloader cache aggressively caches everything! That means if you don't want to cache anymore, just create a new instance of `BatchedHTTPLink`.
|
32 | A good fit for this is every incoming HTTP request in a server environment - on each new HTTP request a new `BatchedHTTPLink` instance is created.
|
33 |
|
34 | ## Batching
|
35 |
|
36 | This library uses array-based batching. Querying 2 queries like this creates the following payload:
|
37 |
|
38 | ```graphql
|
39 | query {
|
40 | Item(id: "1") {
|
41 | id
|
42 | name
|
43 | text
|
44 | }
|
45 | }
|
46 | ```
|
47 |
|
48 | ```graphql
|
49 | query {
|
50 | Item(id: "2") {
|
51 | id
|
52 | name
|
53 | text
|
54 | }
|
55 | }
|
56 | ```
|
57 |
|
58 | Instead of sending 2 separate http requests, it gets combined into one:
|
59 |
|
60 | ```js
|
61 | ;[
|
62 | {
|
63 | query: `query {
|
64 | Item(id: "1") {
|
65 | id
|
66 | name
|
67 | text
|
68 | }
|
69 | }`,
|
70 | },
|
71 | {
|
72 | query: `query {
|
73 | Item(id: "2") {
|
74 | id
|
75 | name
|
76 | text
|
77 | }
|
78 | }`,
|
79 | },
|
80 | ]
|
81 | ```
|
82 |
|
83 | **Note that the GraphQL Server needs to support the array-based batching!**
|
84 | (Prisma supports this out of the box)
|
85 |
|
86 | ## Even better batching
|
87 |
|
88 | A batching that would even be faster is alias-based batching. Instead of creating the array described above, it would generate something like this:
|
89 |
|
90 | ```js
|
91 | {
|
92 | query: `
|
93 | query {
|
94 | item_1: Item(id: "1") {
|
95 | id
|
96 | name
|
97 | text
|
98 | }
|
99 | item_2: Item(id: "2") {
|
100 | id
|
101 | name
|
102 | text
|
103 | }
|
104 | }`
|
105 | }
|
106 | ```
|
107 |
|
108 | This requires a lot more logic and resolution magic for aliases, but would be a lot faster than the array based batching as our tests have shown!
|
109 | Anyone intersted in working on this is more than welcome to do so!
|
110 | You can either create an issue or just reach out to us in slack and join our #contributors channel.
|
111 |
|
112 | ## Help & Community [![Slack Status](https://slack.graph.cool/badge.svg)](https://slack.graph.cool)
|
113 |
|
114 | Join our [Slack community](http://slack.graph.cool/) if you run into issues or have questions. We love talking to you!
|
115 |
|
116 | ![](http://i.imgur.com/5RHR6Ku.png)
|