はじめに
2023年アドベントカレンダー7日目です。
前回の続きで「開発者はWebの開発を進めることができる」を進めていきます。
GraphQL Code Generator
GraphQL Code Generatorとは
Install
web/
npm i graphql
npm i -D typescript @graphql-codegen/cli
initコマンドが用意されているのでそれを使用してみます。
npx graphql-code-generator init
Welcome to GraphQL Code Generator!
Answer few questions and we will setup everything for you.
? What type of application are you building?
どのアプリケーションを使用していますか?
⇒ Application built with React
? Where is your schema?: (path or url)
Schemaファイルはどこにありますか?
⇒ ./schema.graphql
? Where are your operations and fragments?:
オペレーションやフラグメントはどこにありますか?
⇒ src/graphql/*.graphql
? Where to write the output
アウトプットファイル先はどこにしますか?
⇒ src/graphql/generated.tsx
? Do you want to generate an introspection file?
イントロスペクションファイルを生成しますか?
⇒ No
? How to name the config file? codegen.ts
コンフィグファイルの名前はどうしますか?
⇒ codege.ts(default)
? What script in package.json should run the codegen?
スクリプトの名前はどうしますか?
⇒ codegen
schema.graphql
type Blog {
title: String!
author: String!
body: String!
createdAt: String!
}
type Query {
blogs: [Blog!]!
}
src/graphql/operation.graphql
query GetBlogs {
blogs {
...BlogFields
}
}
fragment BlogFields on Blog {
title
author
body
createdAt
}
これで生成準備は整いました
Apollo Client
Apollo Clientを使ってWebからリクエストを送るつもりなので、そのあたりの設定をしていきます。
web/
npm install @apollo/client
npm install --save-dev @graphql-codegen/typescript-react-apollo
codegen.ts
import type { CodegenConfig } from '@graphql-codegen/cli'
const config: CodegenConfig = {
overwrite: true,
schema: './schema.graphql',
documents: 'src/graphql/*.graphql',
generates: {
'src/graphql/generated.tsx': {
plugins: [
'typescript',
'typescript-operations',
'typescript-react-apollo',
],
},
// mockサーバー側のSchemaファイルを生成
'mock/schema.graphql': {
plugins: ['schema-ast'],
},
},
}
export default config
npm run codegen
きちんとファイルが生成されていたら完了です
src/graphqll/generated.tsx
src/graphqll/generated.tsx
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
export type Maybe<T> = T | null;
export type InputMaybe<T> = Maybe<T>;
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };
export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };
export type MakeEmpty<T extends { [key: string]: unknown }, K extends keyof T> = { [_ in K]?: never };
export type Incremental<T> = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never };
const defaultOptions = {} as const;
/** All built-in and custom scalars, mapped to their actual values */
export type Scalars = {
ID: { input: string; output: string; }
String: { input: string; output: string; }
Boolean: { input: boolean; output: boolean; }
Int: { input: number; output: number; }
Float: { input: number; output: number; }
};
export type Blog = {
__typename?: 'Blog';
author: Scalars['String']['output'];
body: Scalars['String']['output'];
createdAt: Scalars['String']['output'];
title: Scalars['String']['output'];
};
export type Query = {
__typename?: 'Query';
blogs: Array<Blog>;
};
export type GetBlogsQueryVariables = Exact<{ [key: string]: never; }>;
export type GetBlogsQuery = { __typename?: 'Query', blogs: Array<{ __typename?: 'Blog', title: string, author: string, body: string, createdAt: string }> };
export type BlogFieldsFragment = { __typename?: 'Blog', title: string, author: string, body: string, createdAt: string };
export const BlogFieldsFragmentDoc = gql`
fragment BlogFields on Blog {
title
author
body
createdAt
}
`;
export const GetBlogsDocument = gql`
query GetBlogs {
blogs {
...BlogFields
}
}
${BlogFieldsFragmentDoc}`;
/**
* __useGetBlogsQuery__
*
* To run a query within a React component, call `useGetBlogsQuery` and pass it any options that fit your needs.
* When your component renders, `useGetBlogsQuery` returns an object from Apollo Client that contains loading, error, and data properties
* you can use to render your UI.
*
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
*
* @example
* const { data, loading, error } = useGetBlogsQuery({
* variables: {
* },
* });
*/
export function useGetBlogsQuery(baseOptions?: Apollo.QueryHookOptions<GetBlogsQuery, GetBlogsQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<GetBlogsQuery, GetBlogsQueryVariables>(GetBlogsDocument, options);
}
export function useGetBlogsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<GetBlogsQuery, GetBlogsQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<GetBlogsQuery, GetBlogsQueryVariables>(GetBlogsDocument, options);
}
export function useGetBlogsSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions<GetBlogsQuery, GetBlogsQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useSuspenseQuery<GetBlogsQuery, GetBlogsQueryVariables>(GetBlogsDocument, options);
}
export type GetBlogsQueryHookResult = ReturnType<typeof useGetBlogsQuery>;
export type GetBlogsLazyQueryHookResult = ReturnType<typeof useGetBlogsLazyQuery>;
export type GetBlogsSuspenseQueryHookResult = ReturnType<typeof useGetBlogsSuspenseQuery>;
export type GetBlogsQueryResult = Apollo.QueryResult<GetBlogsQuery, GetBlogsQueryVariables>;
これでWebの開発が進められるようになりました。
次回からは、TOPページの作成に入ります