👾

ReactとGraphql(hygraph)でcodegenでAPIの型生成

2024/09/26に公開

はじめに

久々にReactとGraphQLを触ったのでGraphQLとかの記憶がかなりなくなっていたのでまとめておきます。

以下環境です。

ライブラリ バージョン
react 18.3.1
typescript 4.9.5
@apollo/client 3.11.8

またGraphQLCMSにはhygraphを使用しております。
理由としては一番オーソドックスかなと思ったためでです。

ビルドツールにはviteではなく、webpackで対応しました。

reactのプロジェクト作成

公式にもある通り以下のように--template typescriptでts環境でreactを記載できるっぽい

npx create-react-app my-app --template typescript

初回はつけていなくて.jsで生成されました。(viteはここはquestionを投げてくれカスタマイズできるので楽でしたね。。。)

codegenを導入

公式にもある通りClient Presetが主流らしいですね。またGraphQL Code Generator v5 Roadmap的にもv3から推奨されていそうです。

上記の通り個人的な見解としてもcodegenをwatchする際に容量が軽くすみそうだなと思っています。

1.必要ライブラリのインストール

npm install graphql
npm install --dev @graphql-codegen/cli @graphql-codegen/client-preset @parcel/watcher

2.codegenファイルの記載

codegenファイルもymlではなくtsファイルで記載するのが主流らしいですね。

codegen.ts
import type { CodegenConfig } from '@graphql-codegen/cli';

const config: CodegenConfig = {
    schema: `https://${process.env.REACT_APP_HYGRAPH_REGION}.cdn.hygraph.com/content/${process.env.REACT_APP_HYGRAPH_ID}/master`,
    documents: ['**/*.tsx'], // クエリがある階層を識別しそこから型を生成する
    ignoreNoDocuments: true, // watchした際にクエリが見つからない場合に終了しないように定義
    generates: {
        './src/gql/': { // 型ファイルの生成ディレクトリ
            preset: 'client' // プリセットリストをクライアントで対応
        }
    }
}

export default config

3.GraphQLへアクセスするApolloClient記述の書き替え

また最終的にcodegen導入前と導入後のfetchファイルの比較は以下にになりました。

導入後.ts
- import { ApolloClient, InMemoryCache, gql, useQuery } from '@apollo/client';
+ import { ApolloClient, InMemoryCache, useQuery } from '@apollo/client';
+ import { graphql } from '../gql/gql'; // gglファイルがあるディレクトリの指定

const hygraphRegion = process.env.REACT_APP.HYGRAPH_REGION;
const hygraphId = process.env.REACT_APP.HYGRAPH_ID;

const client = new ApolloClient({
  uri: `https://${hygraphRegion}.cdn.hygraph.com/content/${hygraphId}/master`,
  cache: new InMemoryCache(),
});

- const GET_ALLPAGE_QUERY = gql`
+ const GET_ALLPAGE_QUERY = graphql(`
  query GetNavigation {
    pages(locales: en){
      slugd
    }
  }
`);

export const fetchPage = () => {
  return useQuery(GET_ALLPAGE_QUERY);
}

4.scriptsの更新

またpackage.jsonのscriptに以下を入れ実行。

"graphql-codegen": "npx graphql-code-generator --require dotenv/config --config ./src/codegen.ts --watch"
"{任意のスクリプト名}": "npx graphql-code-generator --require dotenv/config --config {codegen.tsの格納ディレクトリ} --watch"

出来ました。
またクエリ等を間違えたらwatchしているので、以下エラーが出るのでクエリの間違いがわかって良いですね`!

    ✔ Load GraphQL schemas
    ✔ Load GraphQL documents
    ✖ GraphQL Document Validation failed with 1 errors;
Error 0: Cannot query field "items" on type "Query". Did you mean "users"?

まとめ

個人的にはクエリをどこかにひとまとめにした方がwatchする範囲をさらに絞れて作業効率を図れそうと思いました。
またまだまだGraphQL初心者なので引き続き色々と記事を書いていきます。

Discussion