はじめに
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);
}
};
参考文献