Skip to content

Instantly share code, notes, and snippets.

@ssbb
Last active November 5, 2022 21:06
Show Gist options
  • Save ssbb/a71c43d34c8dca5fbc4971ef5d643613 to your computer and use it in GitHub Desktop.
Save ssbb/a71c43d34c8dca5fbc4971ef5d643613 to your computer and use it in GitHub Desktop.
Next.js graphql-request example
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, {});
});
@ssbb
Copy link
Author

ssbb commented Nov 4, 2022

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.

@ssbb
Copy link
Author

ssbb commented Nov 4, 2022

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).

@eric-burel
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment