npm i -D @graphql-codegen/cli
npm i -D @graphql-codegen/client-preset
npm i -D @graphql-codegen/typescript-react-query
codegen.ts
import { CodegenConfig } from "@graphql-codegen/cli";
const config: CodegenConfig = {
schema: "http://localhost:4100/graphql",
documents: ["./src/graphql/**/*.graphql"],
ignoreNoDocuments: true, // for better experience with the watcher
hooks: { afterAllFileWrite: ["prettier --write"] },
generates: {
"./src/graphql/generated.ts": {
plugins: [
"typescript",
"typescript-operations",
"typescript-react-query",
{
add: {
content: "// generated by graphql-codegen. DO NOT EDIT.",
},
},
],
config: {
fetcher: "fetch",
// fetcher: {
// func: "graphql/custom-fetcher#useFetchData",
// isReactHook: true,
// },
},
},
},
};
export default config;
fetcher の指定でよく使うのは、"fetch", "graphql-request", または
fetcher: {
func: "./custom-fetcher#useFetchData",
isReactHook: true,
},
です。
src/graphql/custom-fetcher.ts を以下のような内容で作成します (例、next.js + firebaesトークンを自動取得)
import { getAccessToken } from "@/libs/firebaseAuth";
export const useFetchData = <TData, TVariables>(
query: string,
options?: RequestInit["headers"],
): ((variables?: TVariables) => Promise<TData>) => {
return async (variables?: TVariables) => {
if (!process.env.NEXT_PUBLIC_API_BASE_URL) {
throw new Error("NEXT_PUBLIC_API_BASE_URL is not set");
}
const url = process.env.NEXT_PUBLIC_API_BASE_URL + "/graphql";
const token = await getAccessToken(true);
const res = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
...(options ?? {}),
},
body: JSON.stringify({
query,
variables,
}),
});
const json = await res.json();
if (json.errors) {
const { message } = json.errors[0] || "Error..";
throw new Error(message);
}
return json.data;
};
};
src/graphql/queries/UsersFindAll.graphql
query UsersFindAll {
usersFindAll {
id
email
name
authProvider
authId
createdAt
updatedAt
}
}
自動生成の実行
graphql-codegen --config codegen.ts
const { data } = useUsersFindAllQuery<UsersFindAllQuery>({
endpoint: "http://localhost:4000/graphql",
fetchParams: {
headers: {
"content-type": "application/json",
"Authorization": `Bearer ${token}`,
},
},
});
const { data } = useUsersFindAllQuery();