見出し画像

GraphQLが変えるAPIの世界

みなさんこんにちは、@ultaroです!

REST APIはデータの取得が出来たり、ビジネスロジックを実行したり、何らかの処理を共有する方法としてとても便利ですね!でもちょっと使いづらいな、と困ったことはありませんか?

GraphQL
を使えばREST APIの困りごとを解決することができます!

この記事では、REST APIの良くある困りごとと、その困りごとをGraphQLはどのように解決するのかについて説明していきます。


1.GraphQLとは

GraphQLは、APIを構築するためのクエリ言語および実行エンジンです。

Facebookによって2015年に開発され、オープンソース化された後、徐々に広がりを見せています。REST APIの代替手段として、多様なクライアントに対応するシステムや複雑なデータ構造を持つシステムで注目を集めています。

GraphQLの特徴には以下のようなものがあります。

(A)取得したいデータを定義する

まずは下記のリクエスト/レスポンスの例を見てください。ECサイトでの商品の例です。

  • リクエスト例

query {
  product(id: "123") {
    id
    name
    price
    description
    images
    reviews {
      user
      rating
      comment
    }
    relatedProducts {
      id
      name
      price
      image
    }
  }
}
  • レスポンス例

{
  "data": {
    "product": {
      "id": "123",
      "name": "Wireless Bluetooth Headphones",
      "price": 299.99,
      "description": "High-quality wireless Bluetooth headphones with noise-cancellation feature.",
      "images": [
        "https://example.com/images/product123/main.jpg",
        "https://example.com/images/product123/side.jpg"
      ],
      "reviews": [
        {
          "user": "John Doe",
          "rating": 5,
          "comment": "Excellent sound quality and battery life!"
        }
      ],
      "relatedProducts": [
        {
          "id": "124",
          "name": "Wireless Bluetooth Earbuds",
          "price": 199.99,
          "image": "https://example.com/images/product124/main.jpg"
        },
        {
          "id": "125",
         ・・・・・・
        }
      ]
    }
  }
}

GraphQLのクエリが、レスポンスと同じ形状を持っているのがわかりますよね?

GraphQLではクエリを発行するフロントエンドと、APIを提供するバックエンドで、グラフ構造のスキーマを共有しています。

このため、フロントエンドでは返されるデータの形が予測しやすく、必要なデータを選択してクエリを作成できます。

(B)データ構造の階層化

GraphQLはグラフスキーマを前提としたオブジェクト間の関連を自動で追跡してデータを取得します。これにより、RESTfulサービスで必要とされる複数回のリクエストや複雑なSQLの結合ステートメントが不要になります。

(A)の例ではproductsに対して、reviewsとrelatedProductsが階層構造的にぶら下がっていますが、1回のリクエストで取得できています。

(C)GraphQLはプロトコル

GraphQLで定義された各フィールドは、サーバー側のデータソースとマッピングされます。既存のデータベースやWebAPIを活用してデータが取得できます。やるべきはフィールドと、サーバー側のデータソースとマッピングです。

2. REST APIの困りごとをGraphQLでどう解決するか

REST APIの困りごと①:オーバーフェッチ/アンダーフェッチ

REST APIでは特定のエンドポイントによって提供されるデータが固定されています。これにより、クライアントが必要なデータよりも多くのデータを取得するオーバーフェッチや、必要なデータが不足しているアンダーフェッチの問題が発生します。

オーバーフェッチが発生すると余計なデータの分トラフィックは過剰になりますし、アンダーフェッチが発生すると必要な情報が取得できるまで何度もAPIを呼び出すことになってしまいます。

では、なぜREST APIでオーバーフェッチ/アンダーフェッチが起こるのか、具体的な例を見てみましょう。

ECサイトを例とします。

商品詳細画面用にAPIを作りました。この画面には商品名(name)、価格(price)、画像(images)、説明(description)、レビュー(reviews)が表示されます。

APIは画面に必要なデータをすべて返すように設計しました。この時点では何の問題もないですね!

商品詳細画面に合わせてAPIを設計


次にスマホ画面対応することになりました。スマホの画面は小さいため、表示する情報をコンパクトにしなければなりません。

・・・情報を取捨選択して、レビューを表示するのはやめてしまいましょう。表示する商品画像も1つだけにしました。

すると最初に作ったAPIでは画面で利用しない、不要なデータ(下図のレスポンスの黄文字部分)も取得されることになってしまいました。

これがオーバーフェッチです。

オーバーフェッチ

さらに続いて商品関連のさまざまな情報が参照できるダッシュボード画面を作成しました。

しかしダッシュボードには最初に作ったAPIの項目ではデータが足りません。

商品データのほかに、それに紐づく売上(sales)などのデータも取得したいのですが、この情報を取得するには他のAPIを実行しなければなりません。

これがアンダーフェッチです。

アンダーフェッチ


このようにしてREST APIではオーバーフェッチ/アンダーフェッチが頻繁に発生します。


一方GraphQLでは、クライアントからはグラフスキーマを前提とした柔軟なクエリを実行でき、必要なデータだけを要求できます。

つまりクライアントは、必要なデータのみをリクエストし、サーバーはそれに応じてレスポンスを返します。これにより、過不足無くデータの取得を行うことができます。

不要なデータの取得を防ぐことにより、ネットワークトラフィックを削減することができ、また1回のクエリ実行でデータに不足が起こらないため複数のクエリを実行する必要もありません。

オーバーフェッチにならない
アンダーフェッチにならない


REST APIの困りごと②:過剰なエンドポイントの管理

REST APIでは、各リソースに対してエンドポイントが必要です。これにより、リソースごとに異なるエンドポイントを管理する必要があります。

リソースごとのエンドポイント

加えて、困りごと①で紹介した「オーバーフェッチ/アンダーフェッチ」をの発生抑えるために、異なるデバイスや画面ごとに専用のAPIを用意することがあります。すると、どんどんどんどんエンドポイントが増えていき、管理が複雑になります😨

リソースごと+デバイスや画面ごとに増えるエンドポイント

これに対しGraphQLでは、1つのエンドポイントで複数のリソースにアクセス可能です。エンドポイントが1つで済むことから、APIの管理が簡略化されます。

GraphQLのエンドポイントは単一


REST APIの困りごと③:バージョン管理の複雑化

REST APIでは、エンドポイントの変更や追加がある場合に、過去バージョンのAPIのサポートも必要な場合があり、バージョン管理が複雑化します。

GraphQLでは、クライアントが必要なデータをクエリで指定するため、APIの変更や追加がクライアントに影響を与えません。これはGraphQLの柔軟性により、新しいフィールドやリレーションシップを追加しても既存のクエリに影響を与えることがないためです。したがって、(破壊的なスキーマ定義変更をしないかぎり)GraphQLを使用すると、APIのバージョン管理が不要ということになります。

3. まとめ

GraphQLはREST APIが抱える様々な困りごとを解決してくれます。

REST API vs GraphQL

REST APIに比べて学習コストや設計難易度が高い という点を除けば、GraphQLはかなり優秀です✨

API構築時の選択肢に入れてみてはいかがでしょうか?

この記事が気に入ったらサポートをしてみませんか?