35
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

GraphQL を試す

Posted at

概要

フロントに React を使っているので、通信に Relay を使えないかと調査を始めましたが、API が REST ではなく GraphQL ということに気づき、まずは GraphQL の構文をいろいろ試してみることにしました。

Relay のチュートリアルで動作するサーバーに GraphQL を実行できる UI がついていたので、そこで試してみます。

公式チュートリアル

公式のチュートリアル を一通り行うと、宝探しゲームが完成します。

これを使いながら GraphQL を学んでいきます。

サーバーの起動

チュートリアル後のコードのイメージをこちら (tag tutorial)にコミットしました。

起動は下記のように実行してください。

npm install
npm run update-schema
npm start

ブラウザからhttp://localhost:3000 をブラウザで開くとゲームができます。

GraphQL のテスト用画面

GraphQL API は http://localhost:8080 で、ルートをブラウザで開くとテスト用の UI を表示できます。

graphql-ui.png

↑のような画面が表示されます。

「>」ボタンで実行、Docs には dada/schema.js で定義した schema が整形されて表示されます。
また、(分かりにくいですが、)左下の QUERY VARIABLES をクリックするとクエリーの変数を入力できます。

GraphQL を試す

Docs をクリックすると、query と mutation の2つが出てきます。 query はデータの取得、 mutation はデータの更新をするときに使います。

game の取得を試します。
左の "Welcome ~" と書かれた左の領域に {game} と入力し、実行 (>) します。

右に結果が出ますが、今回は下のようにエラーが表示されます。

{
  "errors": [
    {
      "message": "Field \"game\" of type \"Game\" must have a sub selection.",
      "locations": [
        {
          "line": 15,
          "column": 2
        }
      ]
    }
  ]
}

さらに入力した {game} も下のように変更されます。

{game {
  id
}}

これは game のどのフィールドを取得するか指定されていないため、エラーとなります。また、システムが理解できる範囲で入力が修正されます。
ここで再度実行すると、今度はクエリーの結果が表示されます。

{
  "data": {
    "game": {
      "id": "R2FtZTox"
    }
  }
}

Docs -> Query -> Game (またはdada/schema.js)を見ると、Game には id, hidingSpots, turnsRemaining の3つのフィールドがあることがわかります。

入力を次のように変えてみます。

{
  game {
    id
    turnsRemaining
  }
}

実行すると結果に turnsRemaining も含まれます。

さらに クエリーに hidingSpots を追加します。

{
  game {
    id
    turnsRemaining
    hidingSpots
  }
}

またエラーになり、クエリーが次のように修正されます。

{
  game {
    id
    turnsRemaining
    hidingSpots {
      edges {
        node {
          id
        }
      }
    }
  }
}

hidingSpots もオブジェクトのリストなので、どの情報を取得するのか指定する必要があります。

{
  game {
    id
    turnsRemaining
    hidingSpots {
      edges {
        node {
          id
          hasBeenChecked
          hasTreasure
        }
      }
    }
  }
}

宝探しの隠し場所(hidingSpot)の一覧が取得できました。

ここで一旦ゲーム画面(http://localhost:3000)に戻ります。
※ ゲームで遊んでしまった人は、サーバーに状態が残っているので、サーバーを再起動してください。

ゲーム画面で適当なマスをクリックします。
もう一度上のクエリーを実行すると、更新したマスの情報が取得できます。

            :
          {
            "node": {
              "id": "SGlkaW5nU3BvdDox",
              "hasBeenChecked": false,
              "hasTreasure": null
            }
          },
          {
            "node": {
              "id": "SGlkaW5nU3BvdDoy",
              "hasBeenChecked": true,
              "hasTreasure": false
            }
          },
          {
            "node": {
              "id": "SGlkaW5nU3BvdDoz",
              "hasBeenChecked": false,
              "hasTreasure": null
            }
          },
            :

次の更新クエリーで使用するので、hasBeenCheckedfalse のノードの id の値をメモしておいてくください。(上の例ならSGlkaW5nU3BvdDozなど)

更新のクエリー

更新のクエリーですが、とりあえず実行してみます。
まず、次のように入力します。

mutation Mutation($input:CheckHidingSpotForTreasureInput!) {
  checkHidingSpotForTreasure(input:$input) {
    clientMutationId
  }
}

次に QUERY VARIABLES (入力欄が見えないときはクリックしてください)に次のように入力します。

{
  "input":{
    "id":"SGlkaW5nU3BvdDoz",
    "clientMutationId":"0"
  }
}

id の値は前にメモしておいた hidingSpotid に変更してください。

ゲーム画面をリロードしたり、次のクエリーを実行すると更新されていることがわかります。

{
  game {
    id
    turnsRemaining
    hidingSpots {
      edges {
        node {
          id
          hasBeenChecked
          hasTreasure
        }
      }
    }
  }
}

更新クエリーの3行目の clientMutationId は Docs の CheckHidingSpotForTreasurePayload のフィールドで、データ取得のクエリーと同様に更新後に取得するフィールドを指定できます。

mutation Mutation($input:CheckHidingSpotForTreasureInput!) {
  checkHidingSpotForTreasure(input:$input) {
    clientMutationId
  }
}

QUERY VARIANTS に指定した値は、CheckHidingSpotForTreasureInputのフィールドです。

最後に

GraphQL に慣れるまではこの UI を使って出力や Docs を見ながらクエリーを組み立てると効率が良さそうです。

本当は Elixir / Phoenix でサーバーも実装してみたいのですが、まだライブラリがなく、自分で実装するには難しいのでもう少し力がついてからやってみようと思います。

Relay のチュートリアルが ES7 で書かれていました。近い将来 React も ES6 の class を使って実装することになりそうなので、 mixin など使えなくなる機能の代わりも調べる予定です。

参考

35
34
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
35
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?