# GraphQLの紹介

GitHub GraphQL API を使用するための便利な用語と概念について説明します。

## GraphQLの用語

GitHub GraphQL API は、GitHub REST API からのアーキテクチャと概念的な変化を表します。 GraphQL API の[リファレンス ドキュメント](/ja/enterprise-server@3.22/graphql)では、いくつかの新しい用語が登場することになるでしょう。

## スキーマ

スキーマは、GraphQL APIの型システムを定義します。 クライアントがaccessできるデータ (オブジェクト、フィールド、リレーションシップ、すべて) の完全なセットについて説明します。 クライアントからの呼び出しは、スキーマに対して[検証](https://graphql.org/learn/validation/)され、[実行](https://graphql.org/learn/execution/)されます。 クライアントは、[イントロスペクション](#discovering-the-graphql-api)を使用してスキーマに関する情報を確認できます。 スキーマはGraphQL APIサーバー上にあります。 詳細については、「[GraphQL API の検出](#discovering-the-graphql-api)」を参照してください。

## フィールド

フィールドは、オブジェクトから取り出せるデータの単位です。
[GraphQL の公式ドキュメント](https://graphql.org/learn/schema/)では、「GraphQL クエリ言語は、基本的にオブジェクトのフィールドを選択するものです」と記載されています。

[公式仕様](https://spec.graphql.org/June2018/#sec-Language.Fields)では、フィールドについても次のように記載されています。

> すべてのGraphQL操作は、明確な形状のレスポンスを保証するために、スカラー値を返すフィールドまで確実に選択を指定しなければなりません。

これはすなわち、スカラーではないフィールドを返させようとすると、スキーマ検証でエラーが投げられるということです。 すべてのフィールドがスカラー値を返すまで、入れ子になったサブフィールドを追加しなければなりません。

## 引数

引数は、特定のフィールドに添付されるキー/値ペアの集合です。 フィールドの中には、引数を必要とするものがあります。
[Mutations](/ja/enterprise-server@3.22/graphql/guides/forming-calls-with-graphql#about-mutations)引数として入力オブジェクトが必要です。

## 実装

GraphQL スキーマでは、\_実装\_という用語を使用して、オブジェクトが[インターフェイス](/ja/enterprise-server@3.22/graphql/reference/interfaces)からどのように継承されるかを定義することがあります。

以下は、インターフェース `X` とオブジェクト `Y` を定義するスキーマの考案された例です。

```graphql
interface X {
  some_field: String!
  other_field: String!
}

type Y implements X {
  some_field: String!
  other_field: String!
  new_field: String!
}
```

これは、オブジェクト `Y` でインターフェース `X` と同じフィールド/引数/戻り値の型が必要とされる一方で、オブジェクト `Y` 固有の新たなフィールドを追加する必要があるということです。 (`!` はそのフィールドが必須であることを意味します。)

リファレンスドキュメントには、以下のような記述があります。

* 各 [オブジェクト](/ja/enterprise-server@3.22/graphql/reference/objects) には、継承元のインターフェイス *が***\[実装**] の下に一覧表示されます。

* 各 [インターフェイス](/ja/enterprise-server@3.22/graphql/reference/interfaces) には、継承 *するオブジェクトが***\[実装]** の下に一覧表示されます。

## 接続

コネクションを使うと、同じ呼び出しの一部として関連するオブジェクトに対するクエリを実行できます。 コネクションを使うと、REST APIでは複数の呼び出しを使うような場合に、単一のGraphQL呼び出しを使うことができます。 詳細については、「[RESTからGraphQLへの移行](/ja/enterprise-server@3.22/graphql/guides/migrating-from-rest-to-graphql)」を参照してください。

点を線でつなぎ、グラフを図示すると役立ちます。 点はノードで、線はエッジです。 コネクションは、ノード間の関係を定義します。

## Edge

エッジは、ノード間のコネクションを表します。 コネクションに対してクエリを行うと、そのエッジをトラバースしてノードを取得することになります。 すべての `edges` フィールドには、`node` フィールドと `cursor` フィールドがあります。 カーソルはページネーションに使用されます。 詳細については、「[GraphQL API におけるページネーションの使用](/ja/enterprise-server@3.22/graphql/guides/using-pagination-in-the-graphql-api)」を参照してください。

## Node

*ノード* はオブジェクトの総称です。 ノードを直接検索することも、接続を介して関連ノードをaccessすることもできます。 指定した`node`が[スカラー](/ja/enterprise-server@3.22/graphql/reference/scalars)を返さない場合は、すべてのフィールドがスカラーを返すまで、サブフィールドを含める必要があります。 REST API を使用してノード ID にアクセスし、GraphQL クエリで使用する方法については、「[グローバルノードIDの利用](/ja/enterprise-server@3.22/graphql/guides/using-global-node-ids)を参照してください。

## GraphQL APIの発見

GraphQL は[内省的](https://graphql.org/learn/introspection/)です。 これはすなわち、GraphQLスキーマに関する詳細をクエリできるということです。

* `__schema` に対してクエリを実行して、スキーマで定義されているすべての型を一覧表示させ、それぞれの詳細を取得します。

  ```graphql
  query {
    __schema {
      types {
        name
        kind
        description
        fields {
          name
        }
      }
    }
  }
  ```

* `__type` に対してクエリを実行して、任意の型の詳細を取得します。

  ```graphql
  query {
    __type(name: "Repository") {
      name
      kind
      description
      fields {
        name
      }
    }
  }
  ```

* \_イントロスペクションクエリ\_を実行するには、`GET`要求を使用することもできます。

  ```shell
  curl -H "Authorization: bearer TOKEN" http(s)://HOSTNAME/api/graphql
  ```

  > \[!NOTE]
  > `"message": "Bad credentials"` または `401 Unauthorized` 応答を受け取った場合は、有効なトークンを使用していることを確認してください。 `403` で `Resource not accessible by personal access token` エラーが発生した場合は、正しいリソース所有者がfine-grained personal access tokenのターゲットとなっていることを確認します。 たとえば、accessしようとしているリポジトリを所有する組織を対象にする必要があります。

  結果はJSONで返されるので、読んだり検索したりしやすくするために、プリティプリントすることをおすすめします。 次の目的のために、[jq](https://stedolan.github.io/jq/) などのコマンドラインツールを使用するか、結果を `python -m json.tool` にパイプできます。

  あるいは、`idl` メディア型を渡して、IDL 形式で結果を返してもらうこともできます。これはスキーマの圧縮バージョンです。

  ```shell
  $ curl -H "Authorization: bearer TOKEN" -H "Accept: application/vnd.github.v4.idl" \
  http(s)://HOSTNAME/api/graphql
  ```

  > \[!NOTE]
  > イントロスペクション クエリは、おそらく GraphQL で実行する唯一の `GET` 要求です。 ボディを渡す場合、GraphQL のリクエストメソッドは、クエリでもミューテーションでも `POST` です。

  クエリの実行の詳細については、「[GraphQLでの呼び出しの作成](/ja/enterprise-server@3.22/graphql/guides/forming-calls-with-graphql)」を参照してください。