👻

GraphQL のクライアント比較

2023/04/17に公開1

GraphQL クライアント比較の概要

GraphQL と書きましたが、「Web アプリで GraphQL 使う場合の HTTP クライアント」についての話が今回の本題です。

GraphQL の Query(値の取得)と Mutation(値の編集)をどの HTTP クライアントから行うのがいい感じなのかについて比較したいと考えています。

クライアントの紹介

今回サンプルを出して比較するのは2つのですが、きっと有名であろうクライアントについて表にしてみました。

項目 説明
axios 言わずと知れた HTTP クライアント界のデファクトスタンダード。その使いやすさや市場シェアからなかなか fetch API が流行らない原因。特別 GraphQL に最適化されているわけではない。
apollo client apollo が GraphQL ではデファクトに近い立ち位置なのでそのクライアントもかなり有名な感じ、簡単に Hook が書けて便利。
urql React のコンサル企業である Formidable によって開発された、新しい grqphql client。
Fetch API XMLHttpRequest と同じで HTTP リクエストを発行する API。JS の API なのでパッケージのインストール等は不要

下準備(テスト用 GraphQL サーバー)

GraphQL のクライアントテストを行うのにサーバーが必要だったので先に作成しましょう。

index.js
import { ApolloServer, gql } from "apollo-server";

let hello = [{ text: "Hello world!" }];

const typeDefs = gql`
  type Hello {
    text: String
  }
  type Query {
    hellos: [Hello!]!
  }
  type Mutation {
    addHello(text: String!): Hello!
  }
`;

const resolvers = {
  Query: {
    hellos: () => {
      return hello;
    },
  },
  Mutation: {
    addHello: (root, args) => {
      const h = { text: args.text };
      hello = [...hello, h];
      return h;
    },
  },
};

const server = new ApolloServer({
  typeDefs,
  resolvers,
});

server.listen().then(({ url }) => {
  console.log(`Server ready at ${url}`);
});
package.json
{
  "name": "server",
  "version": "1.0.0",
  "description": "",
  "type": "module",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  },
  "dependencies": {
    "apollo-server": "^3.10.1"
  }
}

axios のサンプル

それでは実際に GraphQL にアクセスしてデータを取得してくるサンプルアプリを紹介します。

Axios.tsx
import { useEffect, useState } from "react";
import "./App.css";
import axios from "axios";

export default function App() {
  const [message, setMessage] = useState("");

  useEffect(() => {
    const result = axios({
      url: "http://localhost:4000/graphql",
      method: "POST",
      data: {
        query: `
          query {
            hellos {
              text
            }
          }
      `,
      },
    });

    result.then((r) => {
      setMessage(JSON.stringify(r.data.data.hellos));
    });
  }, []);

  return (
    <div className="App">
      <p>{message}</p>
    </div>
  );
}

apollo client のサンプル

続いて apollo client で同様の処理を記載したいと思います。

import { useEffect, useState } from "react";
import "./App.css";
import { ApolloClient, InMemoryCache, gql } from "@apollo/client";

const client = new ApolloClient({
  uri: "http://localhost:4000/graphql",
  cache: new InMemoryCache(),
});

export default function App() {
  const [message, setMessage] = useState("");

  useEffect(() => {
    const result = client.query({
      query: gql`
        query {
          hellos {
            text
          }
        }
      `,
    });

    result.then((r) => {
      setMessage(JSON.stringify(r.data.hellos));
    });
  }, []);
  return (
    <div className="App">
      <p>{message}</p>
    </div>
  );
}

おわりに

今回は2種類のクライアントを紹介しました。

実は Apollo Client は簡単に Hook を作れるのですが、今回結構時間かかってしまったので次回 Apollo Client を利用した Hook 作成を紹介したいと思います。

Discussion

Nakano as a ServiceNakano as a Service

graphql-clientがv8でgraffleに改名したようです

The next version (8) of graphql-request is being renamed to graffle. It has the same base simplicity but with many fixes, enhancements, and major new type safe features. It is not released yet but will be in the coming weeks/months and is already usable. Learn more about it here. You can see the in progress website at https://graffle.js.org.

https://github.com/jasonkuhrt/graffle