1
1

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.

「Introduction to GraphQL」をキャッチアップする

Last updated at Posted at 2018-10-03

AWS AppSyncを始めるにあたり、まずはGraphQLをキャッチアップする必要があったので記事に起こしてみました。

graphql.orgのイントロから、GraphQLを始めるための情報をピックアップします。

足りない部分は今後追記予定。

はじめに

GraphQLとは。

  • クエリ言語の言語仕様である
  • クエリ言語を実行するサーバー側のランタイムも指す

特定のデータストアに結びつく技術ではない。

GraphQLをはじめるために

次の要素が必要。

  • データフィールドと型の定義
  • フィールドに対するデータアクセスの実装
type Query {
  me: User
}

type User {
  id: ID
  name: String
}

データアクセスの実装は、上記の宣言とデータストアを結びつけるもの。GraphQL仕様とは独立した要素だが、必要。

// データアクセスの仮実装
function Query_me(request) {
  return request.auth.user;
}

function User_name(user) {
  return user.getName();
}

上記のような宣言(と実装)に対して、クライアントから me というデータをクエリしてみる。

クエリの表現は下記のようになる。

{
  me {
    name
  }
}

対するGraphQLサービスからのレスポンスの一例は、以下のようなjsonとなる。

{
  "me": {
    "name": "Luke Skywalker"
  }
}

Queries and Mutations

クエリで「欲しいフィールド」を要求することで、GraphQLランタイムは要求されたデータ のみ を返す。クライアントにとって必要なデータだけが返るようになっている。ネストされているデータ構造でも有効。

Auguments

SQLにおける where のようなことができる。以下のクエリでは、 id: "1000" が相当する。

{
  human(id: "1000") {
    name
    height
  }
}

クエリの中で引数を宣言的に記述できるので、パッと見がわかりやすい。

また、 where だけでなくちょっとした関数の適用のような芸当も可能。以下の例では、スカラータイプのフィールドである height に対して、単位を変換して返すようリクエストを行っている。

{
  human(id: "1000") {
    name
    height(unit: FOOT)
  }
}

Aliases

引数のみ異なる複数のフィールドにリクエストをかけたい場合に利用する。
次の例では episode の引数を変えた2つの hero を取り出しており、それぞれに empireHero jediHero というエイリアスを張っている。

{
  empireHero: hero(episode: EMPIRE) {
    name
  }
  jediHero: hero(episode: JEDI) {
    name
  }
}

Fragments

要求するデータ構造で多少複雑なものが欲しくなった時に。

Exampleを見ていると、個人的にはCのインライン関数やマクロあたりに近いイメージを持った。fragmentを定義してクエリ中に宣言することで、その場所に展開される。

下記の例では ...comparisionFields にfragmentsで宣言した構造を展開してリクエストを行う様を確認できる。

{
  leftComparison: hero(episode: EMPIRE) {
    ...comparisonFields
  }
  rightComparison: hero(episode: JEDI) {
    ...comparisonFields
  }
}

fragment comparisonFields on Character {
  name
  appearsIn
  friends {
    name
  }
}

戻ってくるフィールドは leftComparisonrightComparison である。で、それぞれの中身は ...comparisionFields の展開形、つまり fragment comparisonFields の宣言内容に準じるものとなる。

{
  "data": {
    "leftComparison": {
      "name": "Luke Skywalker",
      "appearsIn": [
        "NEWHOPE",
        "EMPIRE",
        "JEDI"
      ],
      "friends": [
        {
          "name": "Han Solo"
        },
        {
          "name": "Leia Organa"
        },
        {
          "name": "C-3PO"
        },
        {
          "name": "R2-D2"
        }
      ]
    },
    "rightComparison": {
      "name": "R2-D2",
      "appearsIn": [
        "NEWHOPE",
        "EMPIRE",
        "JEDI"
      ],
      "friends": [
        {
          "name": "Luke Skywalker"
        },
        {
          "name": "Han Solo"
        },
        {
          "name": "Leia Organa"
        }
      ]
    }
  }
}

Operation name

読んで字の如くで、意図する「操作」を宣言するためのもの。 querymutation subscription の3種類ある。

query に関しては省略記法も利用可能。ここまでのexampleがまさしくで、これらは暗黙的に query を利用している。

query HeroNameAndFriends {
  hero {
    name
    friends {
      name
    }
  }
}

複数のOperationを含むクエリを記述する場合には必須となる。しかし、「操作」を明示的にクエリに含むことがサーバーサイドでのロギング観点で有用であるため、指定することが推奨される。

Variables

(追記予定)

Directives

(追記予定)

Mutations

(追記予定)

Inline Fragments

(追記予定)

参考

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?