LoginSignup
6
2

【Next.js】ApolloClient×GraphQLCodegen 使ってみた

Last updated at Posted at 2023-12-08

はじめに

ApolloClient×GraphqlCodegenの組み合わせががとても書いやすく感動したので、軽く使い方をまとめておきます。
今回はユーザーの登録と取得を例にファイルの生成からAPIを叩くまでの流れを軽く紹介していこうと思います。
間違いがあれば指摘していただけると嬉しいです。

今回使用したライブラリ

@apollo/client
@graphql-codegen/cli
@graphql-codegen/typescript
@graphql-codegen/typescript-operations
@graphql-codegen/typescript-react-apollo
@graphql-codegen/client-preset
@graphql-codegen/introspection

codegen.yml

生成されるファイルの種類やオプションを定義します。
この設定により,、型定義やHooksが自動生成されます。

overwrite: true
schema: "schema.graphql"
documents: "src/**/*.gql"
generates:
  src/generated/graphql.ts:
    plugins:
      - "typescript"
      - "typescript-operations"
      - "typescript-react-apollo"
    config:
      withHooks: true 
      withComponent: false
      withHOC: false

overwrite:
既存のファイルを上書きするかどうか。

schema:
スキーマファイルのパス。

documents:
ドキュメント(クエリ、ミューテーション等)のパス。

generates:
生成されたファイエルの配置場所

plugins:
各種プラグイン 個別インストールが必要

config:
withHooks:
Apollo Client用のカスタムフックの自動生成有効
withComponent: withHOC: false
Reactコンポーネントと高階コンポーネントの自動生成無効

package.json

自動生成のコマンドを定義します

scripts{
    "codegen": "graphql-codegen --config codegen.yml"
}

schema.gql

使用するデータ型やAPIのクエリ、ミューテーションを定義します。

scalar Upload
type User {
  userId: ID!
  email: String!
  name: String!
}

type Query {
  user(userId: ID!): User
}

type Mutation {
  createUser(name: String!): User
}

document

GraphQLのドキュメントは、アプリケーションが実際にGraphQLサーバーに送信する操作を定義します。以下の例では、ユーザーを取得し、新しいユーザーを作成する操作を定義しています。

//User.gql

query GetUser($userId: ID!) {
  user(userId: $userId) {
    userId
    email
    name
  }
}

mutation CreateUser($name: String!) {
  createUser(name: $name) {
    userId
    email
    name
  }
}

生成コマンド

このコマンドを実行することで、codegen.ymlに定義された設定に基づいて、ファイルが自動生成されます。

 npx graphql-codegen    

apolloの準備

HTTPリンクと認証リンク、Apollo Clientインスタンスを作成します。

import { ApolloClient, InMemoryCache, createHttpLink } from "@apollo/client";
import { setContext } from "@apollo/client/link/context";

const httpLink = createHttpLink({
  uri: "http://hogehoge"
});

const authLink = setContext((_, { headers }) => {
  const token = localStorage.getItem("token");
  return {
    headers: {
      ...headers,
      authorization: token 
    },
  };
});

const client = new ApolloClient({
  link: authLink.concat(httpLink),
  cache: new InMemoryCache(),
});



import type { AppProps } from "next/app";
import { ApolloProvider } from "@apollo/client";
import client from "@/lib/apollo/client";

export default function App({ Component, pageProps }: AppProps) {
  return (
    <ApolloProvider client={client}>
      <AuthProvider>
        <Component {...pageProps} />
      </AuthProvider>
    </ApolloProvider>
  );
}

Query叩いてみる

ApolloClientのuseQueryフックを使用して、サーバーからデータを取得します。

import { useQuery } from "@apollo/client";
import {
  GetUserDocument, 
  GetUserQuery,          
  GetUserQueryVariables, 
} from "@/generated/graphql";


export const useGetUser = (userId: string) => {
  const { data, loading, error } = useQuery<
    GetUserQuery,
    GetUserQueryVariables
  >(GetUserDocument, {
    variables: { userId: userId },
  });
  return { data, loading, error };
};


export default function Home() {
  const { data, loading, error } = useGetUser(userId!);
  if (loading) return <div>loading...</div>;
  if (error) return <div>error</div>;
  return (
      <div>{data.name}</div>
  );
}

mutation叩いてみる

ApolloClientのuseMutationフックを使用して、サーバーにデータを変更するリクエストを送信します。

import { useMutation } from "@apollo/client";
import {
  CreateUserMutation,
  CreateUserMutationVariables,
  CreateUserDocument,
} from "@/generated/graphql";

export const useCreateUser = () => {
  const [createUser, { data, loading, error }] = useMutation<
    CreateUserMutation,
    CreateUserMutationVariables
  >(CreateUserDocument);
  return { createUser, data, loading, error };
};


export const CreateUser = () => {
  const { createUser, data } = useCreateUser();
  
  const handleCreate = async () => {
    try {
        await createUser({
          variables: { name: userName }
        });
        console.log("ユーザー登録完了");
      }
      return data
    } catch (err) {
      console.log(err);
    }
  };

参考文献

6
2
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
6
2