0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GraphQL-Code-Generaterを使ってみた

Posted at

開発中に使って開発体験がよかったので忘備録みたいな感じでまとめます。

開発環境

react v19.2
graphql-codegen/cli v6.1.0
graphql-codegen/typescript v5.0.6
graphql-codegen/typescript-operations v5.0.6
graphql-codegen/typescript-react-apollo v4.3.3

GraphQL Code Generaterとは

  • GraphQLスキーマからコードを生成するツール
  • 型やカスタムフックを生成できる
  • フロントエンドで使う

インストール

npm install -D @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-operations @graphql-codegen/typescript-react-apollo

それぞれの役割

  • graphql-codegen/cli
    codegen.tsやcodegen.ymlなどの設定ファイルを読み込むための

  • graphql-codegen/typescript
    バックエンドで定義したschemaを元にTypeScriptの型を生成

  • graphql-codegen/typescript-operations
    クエリファイルを元にレスポンスの型を生成

  • graphql-codegen/typescript-react-apollo
    graphql-codegen/typescript,
    graphql-codegen/typescript-operations
    で生成される方を元に、Reactのカスタムフックを生成

設定ファイル

私はフロントエンドのルート配下に置きました。

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

const config: CodegenConfig = {
    overwrite: true,                                    //生成ファイルの上書き設定
    schema: 'http://localhost:5050/graphql',            //スキーマファイルの読み込み
    documents: 'src/**/*.graphql',                      //クエリファイルの読み込み
    generates: {
        'src/lib/graphql/generated/graphql.ts': {       //生成ファイルのパス
            plugins: [
                'typescript',
                'typescript-operations',
                'typescript-react-apollo',
            ],
        },
    },
}
export default config;

バックエンドのschema準備

設定ファイルの

クエリファイルの準備

設定ファイルのdocumentsで定義した場所(今回は'src/**/*.graphql')にクエリファイルを作成します。

query GetUsers{ //getしたいときはquery
    users{
        id
        name
        email //必要なデータだけ書く
    }
}

mutation CreateUser($name:String!,$email:String!){
    createUser{
        id
        createdAt
    }
}

コード生成

以下のコマンドを実行します。

npx graphql-codegen

すると設定ファイルのgeneratesで定義した場所(今回は'src/lib/graphql/generated/graphql.ts')
にコードが生成されます。

生成されるコード

主に下記のようなコードが大量に生成されます。(一部抜粋)
生成されたコードを使用するうえでコードを完璧に理解する必要はないかと思います。
カスタムフックも呼び出すだけで大丈夫なのですごく便利です。

スキーマを元にしたデータの原型の型

バックエンドのGraphQLスキーマ(type User等)がそのままTypeScriptの型として定義されています。

export type User = {
  __typename?: 'User';
  id: string;
  name: string;
  email: string; 
  createdAt: any;
};

実際に「取得するデータ」だけの型

自分で書いたクエリ(query GetUsers等)に対応する型が定義されています。
クエリで要求したフィールドしか型に含まれないです。

export type GetUsersQuery = {
  __typename?: 'Query';
  users: Array<{
    __typename?: 'User';
    id: string;
    name: string;
  }>;
};

カスタムフック

上記の型を使ってApolloClientを呼び出すための関数(Hooks)が定義されています。

import * as Apollo from '@apollo/client';

export const useGetUsersQuery = (
  baseOptions?: Apollo.QueryHookOptions<GetUsersQuery, GetUsersQueryVariables>
) => {
  const options = { ...defaultOptions, ...baseOptions };
  
  return Apollo.useQuery<GetUsersQuery, GetUsersQueryVariables>(
    GetUsersDocument,
    options
  );
};

コード生成の効果

GraphQL-Code-Generaterを利用していないコード

import { useQuery, gql } from '@apollo/client';

type User = { id: string; name: string };
type GetUsersData = { users: User[] };

const GET_USERS = gql`
  query GetUsers {
    users { id, name }
  }
`;

export const UserList = () => {
  const { data, loading } = useQuery<GetUsersData>(GET_USERS); 

 if (loading) return <p>Loading</p>;
 
  return(
      //map関数等
  )
}

GraphQL-Code-Generaterを利用したコード

import { useGetUsersQuery } from '../lib/graphql/generated/graphql';

export const UserList = () => {
  const { data, loading, error } = useGetUsersQuery();

  if (loading) return <p>Loading</p>;
  if (error) return <p>Error: {error.message}</p>;

  return (
    //map関数等
  );
};

コード量が減り、非常にすっきりしました。
GraphQLを使用する機会があれば使ってみてください。
雑でしたが以上になります。ありがとうございました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?