Closed14

GraphQL

koizumi7010koizumi7010

目的

仕事でGraphQLを触ることになったが、今までRESTful APIしか開発したことがないのでキャッチアップする

koizumi7010koizumi7010

GraphQLとは

API向けに作られたクエリ言語とのこと
クライアント側で必要なデータ構造を定義することで、サーバーからのレスポンスにはその定義されたのと同じ構造のデータが返される
RESTと比較して効率性が良く、必要なデータしか返さないようになっている
参考:https://ja.wikipedia.org/wiki/GraphQL

koizumi7010koizumi7010

以下のようなdocumentと呼ばれるDSLを実行することで、GraphQLサーバーからクエリ結果(JSON)
が返されるようになっている

// document
{
  tomorrow {
    weather
    rainyPercent
  }
}
{
  "tomorrow": {
    "weather": "cloudy",
    "rainyPercent": 30
  }
}
koizumi7010koizumi7010

RESTful APIでは curl -X GET http://hoge-api/user みたいにURLに対してリクエストを行うが、GraphQLでは上記のようなdocumentを単一のAPIエンドポイントへPOSTするようになっている

koizumi7010koizumi7010

GraphQLサーバーは受け取ったdocument内のフィールドに対応するデータ値を返す
このフィールドに対応する値の取得を担っているのが resolver と呼ばれるもの

クライアント側は要求するデータをdocumentに過不足なく記載し、サーバー側はそれに対応するデータをjsonとして返すことで1回のクエリで要求するデータを取得することができる

この resolver の実装はサービス開発者が行う

koizumi7010koizumi7010

メリット

RESTful APIでは、欲しいデータを取得するのに幾つかのAPIエンドポイントを叩く必要があるが、
GraphQLでは、documentに欲しいデータを構造化してクエリすることで、一回で欲しいデータを取得することができる。

例えば、UserID 100のユーザー情報と商品ID 239の商品を取得したい場合は、RESTful APIだと、ユーザー情報を取得するエンドポイントと、商品データを取得するエンドポイントの2つに問い合わせを行う必要がある。
GraphQLでは、このエンドポイントに縛られずにdocumentに欲しいデータ(ここでは、ユーザーデータと商品データ)を記述することで1回の問い合わせで2つのデータを取得することができる

koizumi7010koizumi7010

Arguments

GraphQLではargumentを用いたクエリ制御が可能になっている
下記のようにdocumentに条件(arguments)を付与することで、それに合致したデータを取得することができる
ここでは、県名が東京で、天気が晴れという条件を付け加えて、その条件に合致した県名と市区町村名 を取得している

// document
{
  prefecture(name: "Tokyo") {
    prefName
    cities(weather: "sunny") {
      cityName
      rainyPercent
}}}
{
  "prefecture": {
    {
      "prefName": "Tokyo",
      "cities": [
        {
          "cityName": "Shinjuku",
          "rainyPercent": 10
        },{
          "cityName": "Ikebukuro",
          "rainyPercent": 0
}]}}}
koizumi7010koizumi7010

directives

directivesとは、特定フィールドのクエリ実行可否などの処理制御を、下記のようなアノテーションをフィールドに付与することで実現することができる
特定の条件でレスポンスに含めたい場合は @include(if: Boolean) を使用する

{
  sinjuku {
    weather
  }
  ikebukuro @include(if: false) {
    weather
    rainyPercent
}}
{
  "sinjuku": {
    "weather": "cloudy"
}}
koizumi7010koizumi7010

GraphQLクライアントの実装にはライブラリの利用は必須ではないが、高機能なものを作る場合は Apollo Client や Relay などのライブラリがよく使われる
GraphQLサーバーの実装には複数の言語が利用可能である(Golangももちろん入っている)

koizumi7010koizumi7010

概要とコンセプトは理解できたので、あとは触ってキャッチアップする

koizumi7010koizumi7010

ちなみに、GraphQLサーバーをgolangで実装するときは gqlgen が有名(というか会社はgqlgenを採用している)

koizumi7010koizumi7010

gqlgenはスキーマ駆動開発を行うライブラリ
https://gqlgen.com/

GraphQLのスキーマ(shema.graphql)を予め定義して、gqlgen generate コマンドを実行するとリゾルバの実装コードが自動生成される
ただ、完璧なコードを自動生成してくれるわけではないので手直しする必要が少しある(goaとかだと自動生成されたファイルは基本いじらない)

koizumi7010koizumi7010

:kore:
1つのリクエストパターン(メソッド・パス)に対して決まったハンドラを1つ用意すればよかったRESTに対して、無数のパターンが存在するリクエストクエリに対してどのようにレスポンスを作っていけばいいのかというGraphQLサーバー側のロジックは、知識がないと想像しにくいのではないでしょうか

このスクラップは2025/02/25にクローズされました