🐬
SWRライブラリを利用したGraphQL APIデータ取得
はじめに
- 以下の記事ではREST APIよりデータ取得したが、GraphQL APIよりデータを取得する。
- Suspenseコンポーネントを利用し、SWRライブラリ経由でデータ取得、その取得結果をコンポーネントへ表示。まずは基本動作。
- GitHub GraphQL APIよりデータを取得する。
- SWRライブラリはVercel社作成ライブラリで、詳細は他の記事が詳しい。
Suspenseタグ内部のコンポーネントのローディングが完了していない場合、propsのfallbackの内容を表示する。
GitHub APIアクセストークン取得
- https://github.com/settings/tokens よりアクセストークンを取得する。
- repoの情報を取得できるように権限設定。
- 取得したアクセストークンを利用し、API経由で情報取得できることを確認する。
- ghp_token 部分に取得したトークンを入力する。
- ヘッダーには「Authorization: bearer」部分まで含めて情報が必要。"data"部のデータ取得を確認。
curl --insecure -H "Authorization: bearer ghp_token" -X POST -d " \
{ \
\"query\": \"query { viewer { login }}\" \
} \
" https://api.github.com/graphql
{"data":{"viewer":{"login":"hiroharu8864"}}}
SWRライブラリによるARI呼び出し ./src/components/hooks/getLoginUser.ts(カスタムフック)
- useSWR
- 1番目引数(key): queryと各variable を配列で指定。key値となるため、variableを合わせて渡す。
- 2番目引数(fetcher): データをフェッチし、Promiseを返す関数を指定。
- 3番目引数(option): オプション指定。この部分に{ suspense: true }を指定する。
- useSWRで取得するデータの戻り値の型を指定。
- getLoginUserQueryで指定したクエリで、データ取得できることを事前にGitHub Explorerにて確認しておく。
import { GraphQLClient } from "graphql-request";
import useSWR from "swr";
import { GitHubData } from "../types/GitHubData";
const getLoginUserQuery = `
query loginUserQuery(
$loginUser: String!
) {
user(login: $loginUser){
id
login
url
}
}
`;
const loginUser = "hiroharu8864";
export const getLoginUser = () => {
const access_token = "ghp_token";
const client = new GraphQLClient("https://api.github.com/graphql", {
headers: {
Authorization: `bearer ${access_token}`,
"Content-Type": "application/json"
},
method: "POST"
});
const { data, error } = useSWR<GitHubData>(
[getLoginUserQuery, loginUser],
(query, login) => client.request(query, { loginUser: login }),
{
suspense: true
}
);
return { data, error };
};
APIレスポンスの型指定 ./src/types/GitHubData.ts
- GraphQL APIの返り値をコンソールログで確認すると以下の型となっている。
- 第一階層: User型を1つ持つObject型
- 第二階層: id, login, urlを持つUser型
- なので、以下のとおり型を定義
export type GitHubData = {
user: User;
};
type User = {
id: string;
login: string;
url: string;
};
出力表示するコンポーネント ./src/components/pages/GraphQLFetch.tsx
import { FC, memo, Suspense, useCallback } from "react";
import { useNavigate } from "react-router-dom";
import { getLoginUser } from "../../hooks/getLoginUser";
const ResultComponent = () => {
const { data, error } = getLoginUser();
return (
<>
<h2>Fetch Login Users Data is below</h2>
<div>
<p>{data?.user.id}</p>
<p>{data?.user.login}</p>
<p>{data?.user.url}</p>
</div>
</>
);
};
export const GraphQLFetch: FC = memo(() => {
const navigate = useNavigate();
const onClickHome = useCallback(() => {
navigate("/");
}, [navigate]);
return (
<>
<Suspense fallback={<p>厄介な広告ページの表示</p>}>
<ResultComponent />
</Suspense>
<button onClick={onClickHome}>to HOME</button>
</>
);
});
- 取得できましたー。
Repository
- Reactの流儀に従うことで、ページのレンダリングとAPIリクエストのタイミングを意識することなく、コーディングできる。
Discussion