NextAuth+SWRでGraphQL APIにOAuthトークン付きでリクエスト(mutation)する
作ったもの
Vercel にデプロイしたもの
ソース
GitHub OAuth App に SignIn したユーザーで、octocat さんのリアクションテスト用 Issue にリアクションできます。
SignIn 時に発行されたアクセストークンは以下のページから無効化できます。
簡単に解説
認証機能(NextAuth)
認証機能の実装は以下の記事で解説しています。
上記記事に記載が無い内容としては、[...nextauth].ts
でscope
を設定しています。
export default NextAuth({
providers: [
Providers.GitHub({
clientId: process.env.GITHUB_ID ?? "",
clientSecret: process.env.GITHUB_SECRET ?? "",
scope: "public_repo", //👈ポイント
}),
],
今回はパブリックリポジトリへのアクセス権限を設定しています(Issue へのリアクションに必要なため)。
例えばこれに加えて user 情報の読み取り権限が必要な場合は
scope: "public_repo read:user"
上記のように半角スペース区切りで設定します。
設定可能な scope の一覧はこちらから確認できます。
取得したトークンは以下で GraphQL Client に設定しています。
const Index = () => {
const [session, loading] = useSession();
const [client, setClient] = useState<GraphQLClient>();
useEffect(() => {
if (session) {
setClient(
new GraphQLClient(API, {
headers: [["Authorization", "bearer " + session.accessToken]], //👈取得したトークンを設定
})
);
}
}, [session]);
GraphQL 実行(SWR)
SWR での GraphQL クエリ実行方法やキャッシュの Key については以下の記事で解説しています。
上記の記事に記載が無い内容として、今回はmutation
(データ更新)を実行しています。
mutation
の場合でもクエリの実行方法自体は変わらないのですが、
実行後にキャッシュ更新(mutate()
)を実行する必要があります。
import { GraphQLClient } from "graphql-request";
import { mutate } from "swr";
/**
* Issueへリアクションを追加する関数
*/
const addReaction = async (client: GraphQLClient, content: string) => {
await client.request(addReactionQuery, { //👈mutation実行
addReactionInput: {
subjectId: subjectId,
content: content,
},
});
void mutate([ //👈ポイント
getIssueReactionsQuery,
repositoryOwner,
repositoryName,
issueNumber,
content,
reactionsLast,
]);
};
この時mutate()
の引数には更新したいキャッシュの Key を指定します。
ここでは今リアクションしているかどうかのステータスを更新したいので、リアクション状態を取得する query 実行時useSWR
の第一引数に渡しているものと同じものを設定します。
const ReactoinStatus: FC<Props> = ({ client, reaction }) => {
const { data: reactionsData, error: reactionsError } = useSWR<Repository>(
[ //👈ポイント
getIssueReactionsQuery,
repositoryOwner,
repositoryName,
issueNumber,
reaction,
reactionsLast,
],
(query, owner, name, number, content, last) =>
client.request(query, {
repositoryOwner: owner,
repositoryName: name,
issueNumber: number,
reactionsContent: content,
reactionsLast: last,
})
);
こうすることでmutation
実行時にキャッシュを更新し、画面を最新の状態に保つことができます。
mutate 時のキャッシュの更新についてはいくつかやり方があり、以下の記事で大変詳しく紹介されていますので、実装に合わせて最適なものを選択してください。
最後に
SWR はまだまだ日本語情報が少なく、 GraphQL を実行しているサンプルがあっても query だけで mutation は無い場合が多いです。
NextAuth も認証するだけでなく、取得した認証情報を使ってあれこれするサンプルは中々ありませんでした。
どちらも非常に便利なライブラリなので、是非いろんな方に使ってみてほしいと思い投稿しました。
この記事が困っている方の力になると嬉しいです。
Discussion