Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
August 10, 2022 12:18 pm GMT

How to use GraphQL and React Query with GraphQL Code Generator (based on Next.Js)

Abstract

GraphQL. REST API schema DB sql .

GQL Query React Query GQL pain point Type Schema , GraphQL Code Generator GQL .

GQL
GQL ?: https://tech.kakao.com/2019/08/01/graphql-basic/

Getting Started

Next.Js TypeScript

Terminal
pnpm create next-app . --typescript  

React Query GQL

Note

React Query TanStack Query Sevelte Query .

Terminal
pnpm add -S @tanstack/react-query graphql graphql-requestpnpm add -D @tanstack/react-query-devtools

dotenv

Terminal
pnpm add -S dotenv

.env.local API URL

GraphQL API Fake GraphQL GraphQLZero .

GraphQLZero Link: https://graphqlzero.almansi.me/

.env.local
NEXT_PUBLIC_GRAPHQL_URL=https://graphqlzero.almansi.me/api

env Type Error next-constants.d.ts default type

next-constants.d.ts
declare namespace NodeJS {    export interface ProcessEnv {        NEXT_PUBLIC_GRAPHQL_URL: string;    }}

react query + gql

react query _app.tsx

Note

const queryClient = new QueryClient({    defaultOptions: {        queries: {            refetchOnMount: false,            refetchOnWindowFocus: false,            refetchOnReconnect: false,        },    },});
pages/_app.tsx
import '../styles/globals.css';import type { AppProps } from 'next/app';import { Hydrate, QueryClientProvider, QueryClient } from '@tanstack/react-query';import { ReactQueryDevtools } from '@tanstack/react-query-devtools';export const queryClient = new QueryClient({    defaultOptions: {        queries: {            refetchOnMount: false,            refetchOnWindowFocus: false,            refetchOnReconnect: false,        },    },});function MyApp({ Component, pageProps }: AppProps) {    return (        <QueryClientProvider client={queryClient}>            <Hydrate state={pageProps.dehydratedState}>                <Component {...pageProps} />;                <ReactQueryDevtools initialIsOpen />            </Hydrate>        </QueryClientProvider>    );}export default MyApp;

GraphQlZero album Resolver Query react query

legacy.tsx .

Note

  • type schema GraphQlZero Docs
interface AlbumQuery {    album: {        id: string;        title: string;        user: {            id: string;            name: string;            username: string;            email: string;            company: {                name: string;                bs: string;            };        };        photos: {            data: {                id: string;                title: string;                url: string;            };        };    };}const albumQueryDocument = gql`    query album($id: ID!) {        album(id: $id) {            id            title            user {                id                name                username                email                company {                    name                    bs                }            }            photos {                data {                    id                    title                    url                }            }        }    }`;
  • getStaticProps Server dehydratedState .
export const getStaticProps = async () => {    await queryClient.prefetchQuery(['album'], useAlbumFetcher);    return {        props: {            dehydratedState: dehydrate(queryClient),        },    };};
pages/legacy.tsx
import type { NextPage } from 'next';import { useQuery, dehydrate } from '@tanstack/react-query';import { request, gql } from 'graphql-request';import { queryClient } from './_app';interface AlbumQuery {    album: {        id: string;        title: string;        user: {            id: string;            name: string;            username: string;            email: string;            company: {                name: string;                bs: string;            };        };        photos: {            data: {                id: string;                title: string;                url: string;            };        };    };}const albumQueryDocument = gql`    query album($id: ID!) {        album(id: $id) {            id            title            user {                id                name                username                email                company {                    name                    bs                }            }            photos {                data {                    id                    title                    url                }            }        }    }`;const useAlbumFetcher = async () =>    await request<AlbumQuery, { id: string }>(        process.env.NEXT_PUBLIC_GRAPHQL_URL,        albumQueryDocument,        {            id: '2',        }    );export const getStaticProps = async () => {    await queryClient.prefetchQuery(['album'], useAlbumFetcher);    return {        props: {            dehydratedState: dehydrate(queryClient),        },    };};const Legacy: NextPage = () => {    const { data } = useQuery<AlbumQuery>(['album'], useAlbumFetcher);    const { album } = data!;    return (        <>            <header style={{ textAlign: 'center' }}>                <h1>Hello GraphQL + React Query !</h1>            </header>            <hr />            <main>                <p style={{ textAlign: 'center', color: 'grey' }}>{JSON.stringify(album)}</p>            </main>        </>    );};export default Legacy;
preview

Image description

gql + react query .

Pain Point .

  • schema Type
  • schema Type Docs

Pain Point GraphQL Code Generator .

GQL Code Generator

Terminal
# code generator core pnpm add -D @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-operations# code generator react query  pnpm add -D @graphql-codegen/typescript-react-query @graphql-codegen/typescript-graphql-request# code generator yaml loader pnpm add -D yaml-loader

codegen.yml

Note

  • schema graphql [filename].graphql . (ts )
  • documents gql schema .
documents: 'graphql/**/!(*.generated).{graphql,ts}'
  • schema GQL URL .
schema: ${NEXT_PUBLIC_GRAPHQL_URL}
codegen.yml
documents: 'graphql/**/!(*.generated).{graphql,ts}'schema: ${NEXT_PUBLIC_GRAPHQL_URL}require:  - ts-node/registergenerates:  graphql/generated.ts:    plugins:      - typescript      - typescript-operations      - typescript-react-query    config:      interfacePrefix: 'I'      typesPrefix: 'I'      skipTypename: true      declarationKind: 'interface'      noNamespaces: true      pureMagicComment: true      exposeQueryKeys: true      exposeFetcher: true      withHooks: true      fetcher: graphql-request

pakage.json graphql-codegen script

package.json
{    ...    "scripts": {        ...        "generate:gql": "graphql-codegen --require dotenv/config --config codegen.yml dotenv_config_path=.env.local"    },    ...}

graphql schema
album schema album.graphql

graphql/album.graphql
query album($id: ID!) {    album(id: $id) {        id        title        user {            id            name            username            email            company {                name                bs            }        }        photos {            data {                id                title                url            }        }    }}


.

structure
. graphql/    album.graphql pages/    _app.tsx    index.tsx    legacy.tsx ...   codegen.yml next-constants.d.ts package.json ...

GraphQL Generator Type, Method

script graphql generated.ts

schema Query Function, Type . ( )

Terminal
pnpm generate:gql Parse Configuration Generate outputs

Query Method Type album

pages new.tsx

legacy.tsx .

Note

  • useQuery useAlbumQuery
const { data } = useAlbumQuery(gqlClient, { id: '3' });
  • prefetchQuery key, fetcher useAlbumQuery.getKey(), useAlbumQuery.fetcher()
await queryClient.prefetchQuery(        useAlbumQuery.getKey({ id: '3' }),        useAlbumQuery.fetcher(gqlClient, { id: '3' })    );
  • Type
  • server spec schema code generate type , .
pages/new.tsx
import type { NextPage } from 'next';import { dehydrate } from '@tanstack/react-query';import { GraphQLClient } from 'graphql-request';import { useAlbumQuery } from '../graphql/generated';import { queryClient } from './_app';const gqlClient = new GraphQLClient(process.env.NEXT_PUBLIC_GRAPHQL_URL);export const getStaticProps = async () => {    await queryClient.prefetchQuery(        useAlbumQuery.getKey({ id: '2' }),        useAlbumQuery.fetcher(gqlClient, { id: '2' })    );    return {        props: {            dehydratedState: dehydrate(queryClient),        },    };};const New: NextPage = () => {    const { data } = useAlbumQuery(gqlClient, { id: '2' });    const { album } = data!;    return (        <>            <header style={{ textAlign: 'center' }}>                <h1>Hello GraphQL + React Query !</h1>            </header>            <hr />            <main>                <p style={{ textAlign: 'center', color: 'grey' }}>{JSON.stringify(album)}</p>            </main>        </>    );};export default New;
preview

Image description

Stackblitz Sample

Conclusion

GraphQL Code Generator Server Spec schema type GQL Pain Point . SSR hydration technique .

REST API . REST API GQL . Backend Frontend Communication Gap GQL .

GQL .

GQL Code Generator .
Link: https://www.graphql-code-generator.com/


Original Link: https://dev.to/soom/how-to-use-graphql-and-react-query-with-graphql-code-generator-based-on-nextjs-23jj

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To