-
-
Save ssbb/a71c43d34c8dca5fbc4971ef5d643613 to your computer and use it in GitHub Desktop.
import { GraphQLClient } from 'graphql-request'; | |
type RequestCache = | |
| 'default' | |
| 'no-store' | |
| 'reload' | |
| 'no-cache' | |
| 'force-cache' | |
| 'only-if-cached'; | |
type Options = { | |
cache?: RequestCache; | |
revalidate?: number; | |
}; | |
export const graphqlClient = (options: Options = {}): GraphQLClient => { | |
const { cache = 'default', revalidate } = options; | |
return new GraphQLClient('http://localhost:4000/graphql', { | |
fetch: (input: RequestInfo | URL, init?: RequestInit) => { | |
return fetch(input, { ...init, next: { revalidate: revalidate } }); | |
}, | |
cache: cache, | |
}); | |
}; |
import { cache } from 'react'; | |
import { graphqlClient } from "lib/graphql-client"; | |
export const myFetch = cache(async () => { | |
const { myDocument } = await graphqlClient().request(myDocument, {}); | |
}); |
But there is some things I can't get (sorry). For Apollo you pass
fetch
options during client initializations.. meanwhile Next now using it on query-level to determine if page/component is static/dynamic or need revalidation etc. So I don't see a way to combine it.
I think you would need to use a page-level API instead, there are ways to force the page to be dynamic or not. You would use a "normal" fetch. We will need to study the internals of Next.js a bit more to understand what this "fetch" thing is a bout and how it translates to GraphQL, I don't think there is an immediate answer, you need to reproduce Next.js features here more than just "using" them.
But there is some things I can't get (sorry). For Apollo you pass
fetch
options during client initializations.. meanwhile Next now using it on query-level to determine if page/component is static/dynamic or need revalidation etc. So I don't see a way to combine it.I think you would need to use a page-level API instead, there are ways to force the page to be dynamic or not. You would use a "normal" fetch. We will need to study the internals of Next.js a bit more to understand what this "fetch" thing is a bout and how it translates to GraphQL, I don't think there is an immediate answer, you need to reproduce Next.js features here more than just "using" them.
So it's basically what I am doing here - caching on nextjs level but totally ignoring graphql node-level cache. It works fine and actually generating static pages or dynamic queries based on cache
/revalidate
param.
Also regarding node-level caching (something like what apollo/urql offers) - I don't think there a way to add something into request/response cycle on Next.js currently (something like entry.server.ts
in remix).
So really what I posted is just what remix-graphql you liked doing (it does not support graphql caching as well).
Makes sense and it should works perfect, especially if you manage to keep requests at page-level.
Speaking of Remix, it reminds me a bit of this article: https://sergiodxa.com/articles/dependency-injection-in-remix-loaders-and-actions
This article shows how you can pass objects in Remix to inject a database connection to loaders, you end up with a "context" object in the action arguments.
In Next 13 this would translate to a "context" props for pages.
I expect Next.js to bring an API somehow like a server context builder, as you do in Apollo server for instance to build the GraphQL context. Processing a GraphQL request server-side is actually a problem very close to parsing the React tree to trigger "useQuery" in each component.
Database connection is actually a bad example because it's shared between all requests, but in this example nothing prevents the developer to also generate and inject request specific objects.
What I posted as a gist is more like to use what nextjs offers as a cache (ISR) + dedup (so you can run the same query during page generation) while don't care about graphql node-level caching.