graphql-fetch-optimizer is a drop-in replacement for nodejs fetch that optimizes GraphQL requests before they are executed
It lets you write queries without worrying about complex optims and it transparently improves how they're executed.
Features include automatic pagination, make all queries sequential (useful with Eleventy SSG), debug mode and more to come if you get involved too
npm install --save graphql-fetch-optimizerIn your build entry point (e.g. .eleventy.mjs or any JS file):
import { createPatchedFetch } from 'graphql-fetch-optimizer'
const patchedFetch = createPatchedFetch(fetch)Then use the patchedFetch() function normally in your code.
import { createPatchedFetch } from 'graphql-fetch-optimizer'
const patchedFetch = createPatchedFetch(fetch)
const res = await patchedFetch('https://cms.example.com/graphql', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
query: `{
menus(first: "auto") {
nodes { id label }
pageInfo { hasNextPage endCursor }
}
}`
})
})
const json = await res.json()
console.log(json.data.menus.nodes)If the menus field contains more than one page of results, the optimizer will fetch all of them and return a merged result.
You can mock all calls to fetch in your code base:
import { createPatchedFetch } from 'graphql-fetch-optimizer'
globalThis.fetch = createPatchedFetch(globalThis.fetch)Options for createPatchedFetch
| Option | Type | Default | Description |
|---|---|---|---|
sequential |
boolean |
false |
If true, paginated root fields are fetched one after another instead of in parallel. Useful for underpowered CMS backends. |
autoKeyword |
string |
auto |
The value used in first: ... arguments to trigger pagination. |
The returned function is a fully-compatible fetch replacement. You can assign it to global.fetch or use it directly.
- Only root-level fields with
first: "auto"are paginated - Your schema must return
nodes[]andpageInfo { hasNextPage, endCursor } - Nested pagination is not supported
Use the core pagination logic manually:
import { fetchRootPaginatedFields } from 'graphql-fetch-optimizer/paginate.js'
const result = await fetchRootPaginatedFields(query, cursorVars, (query, variables) =>
fetch('https://cms.example.com/graphql', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query, variables })
}).then(res => res.json())
)This package is built to evolve as a general-purpose query optimizer. Possible additions:
- Remove unused fragments
- Warn on large or slow responses
- Print query stats or execution plan
- Add a minimum delay between calls
Originally created for Silex no-code static site builder that generates GraphQL queries automatically from a no-code interface
It can also be used in any static generator that fetches GraphQL content at build time