Fragments

フィールドの共通化ができます。

例えば引数が異なりますが取得したい以下のようなクエリがあるとします。

{
  user1: user(login: "foo") {
    id
    bio
    email
  }
  user2: user(login: "bar") {
    id
    bio
    email
  }
}

どちらもidbioemailフィールドが含まれる構造の結果を期待してます。今avatorUrlというフィールドを追加したくなりました。

フィールドの構造がシンプルな今の内は、これに対する対応は「avatorUrlを両方に追加する」でも良いと思いますが、「fragmentで 1 箇所に定義したものを共通して使う」でも対応できます。

{
  user1: user(login: "foo") {
    ...userFragment
  }
  user2: user(login: "bar") {
    ...userFragment
  }
}

fragment userFragment on User {
  id
  bio
  email
  avatarUrl
}

fragmentの構造はfragment foo on FooTypeのような形になります。fooは共通して使う際に指定するもので、適当な名前を付けます。onの次には、idbioemailといったフィールドが所属するタイプ名を置きます。
上記でフラグメントを置いている箇所の定義はuser(login: String!): Userとなっているので、そのタイプはUserである事が分かります。

定義したものはフィールドと同じ箇所で、...を頭に付けてfragmentの名前を置いて使います。(...の後にスペースを挟んでも大丈夫)

fragmentは一部だけが共通といった場合でも使うことができます。例えば、「user2にだけcompanyフィールドを追加したい」と変更があった時以下のように使われているfragmentの下辺りに直接そのフィールドを追加できます。

{
  user1: user(login: "foo") {
    ...userFragment
  }
  user2: user(login: "bar") {
    ...userFragment
    company
  }
}

fragment userFragment on User {
  id
}