🐡

NextからGraphQLのAPIを叩く

2022/12/24に公開2

はじめに

修正や追加等はコメントまたはGitHubで編集リクエストをお待ちしております。

この記事は前回の記事の続きです。

https://zenn.dev/riya_amemiya/articles/d8681e57ae5428

Next のプロジェクト作成

npx create-next-app [project-name] --typescript

GraphQL の導入

yarn add graphql-request graphql

SWR の導入

yarn add swr

GraphQL の API を叩く

認証なし

pages/api/graphql.ts
import { GraphQLClient } from 'graphql-request';
import { NextApiRequest, NextApiResponse } from 'next';
export default async function handler(
    req: NextApiRequest,
    res: NextApiResponse,
) {
    const endpoint =
        process.env.NODE_ENV === 'production'
            ? 'https://.../graphql'
            : 'http://localhost:3001/graphql';
    const graphQLClient = new GraphQLClient(endpoint);
    const data = await graphQLClient.request(
        JSON.parse(req.body).query,
    );
    res.status(200).json({ data });
}

Authorization認証をする場合

pages/api/graphql.ts
import { GraphQLClient } from 'graphql-request';
import { NextApiRequest, NextApiResponse } from 'next';
export default async function handler(
    req: NextApiRequest,
    res: NextApiResponse,
) {
    const endpoint =
        process.env.NODE_ENV === 'production'
            ? 'https://.../graphql'
            : 'http://localhost:3001/graphql';
    const graphQLClient = new GraphQLClient(endpoint, {
        headers: {
            authorization: process.env.AUTH_KEY || '',
        },
    });
    const data = await graphQLClient.request(
        JSON.parse(req.body).query,
    );
    res.status(200).json({ data });
}

フロント

import useSWRMutation from 'swr/mutation';
const fetcher = (url: string, { arg }: { arg: any }) =>
    fetch(url, {
        method: 'POST',
        body: JSON.stringify(arg),
    }).then((r) => r.json());
const { trigger } = useSWRMutation('api/graphql', fetcher);
trigger({
    query: `
   {
    getAllUser {
     email
     gender
     id
     name
    }
   }
   `,
    variables: {},
});

適当な場所に上記のコードを書くと、GraphQLのAPIを叩くことができます。

Discussion

ともお兄さんともお兄さん

記事参考になりました!
ありがとうございます🙇‍

今さっき見つけたばかりなのであってるか全く自信ないのですが
もしかするとfetcherのargはanyじゃなくてArgumentsって型エイリアスでいけるのかもです

import { Arguments } from 'swr'
const fetcher = (url: string, { arg }: { arg: Arguments }) =>
Riya AmemiyaRiya Amemiya

コメントありがとうございます。
提案していただいたコードでも動きましたが、さらに型を強くするために下記コードをおすすめします。

const fetcher = <
  T extends {
    [key: string]: unknown
  }
>(
  url: string,
  {
    arg,
  }: {
    arg: {
      query: string
      variables: T
    }
  },
) =>
  fetch(url, {
    method: 'POST',
    body: JSON.stringify(arg),
  }).then((r) => r.json())