-
-
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, {}); | |
}); |
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.
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.
Yeah looks like you are right. Just tried it now and it works with apollo client I used for
getStaticProps
.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.So previously you don't care about such things too much - you tell nextjs to revalidate whole page at some interval and Apollo resolve cache within this page as well. Now looks like it conflicting. Or I miss something?