# GraphQLでの呼び出しの作成

GraphQL APIの認証方法を学び、クエリとミューテーションの作成と実行方法を学んでください。

## GraphQLでの認証

personal access token、GitHub App、またはOAuth appを使用して GraphQL API に対して認証できます。

### personal access tokenを使用した認証の実行

personal access tokenで認証するには、[個人用アクセス トークンを管理する](/ja/enterprise-server@3.22/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) の手順に従います。 要求しているデータによって、必要なスコープまたはアクセス許可が決まります。

たとえば、トークンがaccessしているリポジトリ内のすべての問題を読み取るための "issues:read" アクセス許可を選択します。

すべての fine-grained personal access tokenには、パブリック リポジトリへの読み取りアクセスが含まれます。
personal access token (classic)を使用してパブリック リポジトリにアクセスするには、"public\_repo" スコープを選択します。

トークンにリソースをaccessするために必要なスコープまたはアクセス許可がない場合、API はトークンに必要なスコープまたはアクセス許可を示すエラー メッセージを返します。

### GitHub Appを使用した認証の実行

組織や他のユーザーに代わって API を使用する場合は、GitHubがGitHub Appを使用することを推奨しています。 お使いのアプリにアクティビティを属性付けするには、そのアプリをアプリ インストールとして認証します。 ユーザーにアプリ アクティビティを属性付けするには、お使いのアプリをユーザーに代わって認証します。 どちらの場合も、GraphQL API に対する認証に使うことができるトークンを生成します。 詳細については、「[GitHub アプリの登録](/ja/enterprise-server@3.22/apps/creating-github-apps/registering-a-github-app/registering-a-github-app) および [GitHub アプリでの認証について](/ja/enterprise-server@3.22/apps/creating-github-apps/authenticating-with-a-github-app/about-authentication-with-a-github-app) を参照してください。

### OAuth appを使用した認証の実行

OAuth appからの OAuth トークンを使用して認証するには、まず、Web アプリケーション フローまたはデバイス フローを使用してOAuth appを承認する必要があります。 その後、受け取ったaccess トークンを使用して、API をaccessできます。 詳細については、「[OAuth アプリの作成](/ja/enterprise-server@3.22/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app) および [OAuth アプリの承認](/ja/enterprise-server@3.22/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps) を参照してください。

## GraphQLのエンドポイント

REST API には多数のエンドポイントがあります。 GraphQL API では、行う操作にかかわらず、エンドポイントは一定のままです。

GitHub Enterprise Server
の場合、そのエンドポイントは次のようになります。

<pre>http(s)://HOSTNAME/api/graphql</pre>

## GraphQLでの通信

GraphQL 操作は複数行の JSON で構成されるため、GitHubは graphQL 呼び出しを行うために [GraphQL クライアント](/ja/enterprise-server@3.22/graphql/guides/using-graphql-clients)を使用することをお勧めします。
`curl` や、HTTP を使うその他のライブラリを使うこともできます。

REST では、[HTTP 動詞](/ja/enterprise-server@3.22/rest#http-verbs)によって実行される操作が決まります。 GraphQL では、クエリまたはミューテーションを実行する場合でも、JSON でエンコードされた本文を提供するので、HTTP 動詞は `POST` となります。 例外は [introspection クエリ](/ja/enterprise-server@3.22/graphql/guides/introduction-to-graphql#discovering-the-graphql-api) であり、エンドポイントに対する単純な`GET`です。 GraphQL と REST の詳細については、「[RESTからGraphQLへの移行](/ja/enterprise-server@3.22/graphql/guides/migrating-from-rest-to-graphql)を参照してください。

`curl` コマンドで GraphQL にクエリを実行するには、JSON ペイロードを使用して `POST` 要求を行います。 ペイロードには、`query` という文字列が含まれている必要があります。

```shell
curl -H "Authorization: bearer TOKEN" -X POST -d " \
 { \
   \"query\": \"query { viewer { login }}\" \
 } \
" http(s)://HOSTNAME/api/graphql
```

> \[!NOTE]
> `"query"` の文字列値は改行文字をエスケープする必要があります。そうしないと、スキーマで正しく解析されません。 `POST` の本文には、外側の二重引用符とエスケープされた内側の二重引用符を使用します。

### クエリ及びミューテーション操作について

GitHubの GraphQL API で許可される 2 種類の操作は、*queries* と *mutations* です。 GraphQL と REST を比較すると、クエリは `GET` 要求と同様に動作しますが、ミューテーションは `POST`/`PATCH`/`DELETE` のように動作します。 変更名によって、実行される変更が決まります。

レート制限の詳細については、「[GraphQL API のレート制限とクエリ制限](/ja/enterprise-server@3.22/graphql/overview/rate-limits-and-query-limits-for-the-graphql-api)」を参照してください。

クエリとミューテーションは似た形式を持っていますが、重要な違いがあります。

### クエリについて

GraphQL クエリからは、指定したデータのみが返されます。 クエリを作成するには、[フィールド内のフィールド](/ja/enterprise-server@3.22/graphql/guides/introduction-to-graphql#field)（\_入れ子になったサブフィールド\_とも呼ばれます）を指定し、スカラーのみが返されるようにする必要があります。

クエリは次のように構成されます。

<pre>query {
  JSON-OBJECT-TO-RETURN
}</pre>

実際の例については、「[クエリの例](#example-query)」を参照してください。

### ミューテーションについて

ミューテーションを作成するには、3つのことを指定しなければなりません。

1. *ミューテーション名*。 実行したい変更の種類です。
2. *入力オブジェクト*。 サーバーに送信するデータ。*入力フィールド* で構成されます。 これはミューテーション名に引数として渡してください。
3. *ペイロード オブジェクト*。 サーバーから返すデータ。*戻り値のフィールド* で構成されます。 これは、ミューテーション名のボディとして渡してください。

ミューテーションはこのように構造化されています。

<pre>mutation {
  MUTATION-NAME(input: {MUTATION-NAME-INPUT!}) {
    MUTATION-NAME-PAYLOAD
  }
}</pre>

この例の入力オブジェクトは `MutationNameInput`、ペイロード オブジェクトは `MutationNamePayload` です。

ミューテーション参照では、入力オブジェクトとして渡す *入力フィールド* が一覧表示されます。 一覧表示されている *戻り値のフィールド* は、ペイロード オブジェクトとして渡されます。

実際の例については、「[ミューテーションの例](#example-mutation)」を参照してください。

## 変数の使用

[変数](https://graphql.org/learn/queries/#variables)を使用すると、クエリをより動的かつ強力にすることができ、ミューテーションの入力オブジェクトを渡すときの複雑さを軽減できます。

以下は、1つの変数を持つクエリの例です。

```graphql
query($number_of_repos:Int!) {
  viewer {
    name
     repositories(last: $number_of_repos) {
       nodes {
         name
       }
     }
   }
}
variables {
   "number_of_repos": 3
}
```

変数を利用するには3つのステップがあります。

1. `variables` オブジェクト内の操作の外部で変数を定義します。

   ```graphql
   variables {
      "number_of_repos": 3
   }
   ```

   オブジェクトは有効なJSONでなければなりません。 この例は単純な `Int` 変数型を示していますが、入力オブジェクトなど、より複雑な変数型を定義できます。 ここで複数の変数を定義することもできます。

2. 変数を操作に引数として渡します。

   ```graphql
   query($number_of_repos:Int!){
   ```

   引数はキーと値のペアで、キーは *名前* (例: ) で `$` 始まり、 `$number_of_repos`値は *型* (例: `Int`) です。 型が必要かどうかを示す `!` を追加します。 複数の変数を定義した場合は、それらをここで複数の引数として含めてください。

3. 変数を操作の中で利用してください。

   ```graphql
   repositories(last: $number_of_repos) {
   ```

   この例では、変数を取得するリポジトリ数に置き換えています。 GraphQLは強い型付けを強制するので、ステップ2で型を指定しています。

このプロセスでクエリの引数は動的になります。 これで、`variables` オブジェクト内の値を変更し、クエリの残りの部分を同じに保つことができます。

変数を引数として使用すると、クエリを変更せずに `variables` オブジェクト内の値を動的に更新できます。

## クエリの例

もっと複雑なクエリを見ていき、これらの情報を流れの中で捉えていきましょう。

次のクエリでは、`octocat/Hello-World` リポジトリを検索し、最新の 20 個の解決された issue を検索し、各 issue のタイトル、URL、最初の 5 つのラベルを返します。

```graphql
query {
  repository(owner:"octocat", name:"Hello-World") {
    issues(last:20, states:CLOSED) {
      edges {
        node {
          title
          url
          labels(first:5) {
            edges {
              node {
                name
              }
            }
          }
        }
      }
    }
  }
}
```

この構造を1行ずつ見ていきましょう。

* `query {`

  目的はサーバーからデータを読み取ることであり、変更することではありません。`query` はルート操作です。 (操作を指定しない場合は、`query` も既定値になります。)

* `repository(owner:"octocat", name:"Hello-World") {`

  クエリを開始するには、[`repository`](/ja/enterprise-server@3.22/graphql/reference/repos#object-repository) オブジェクトを検索します。 スキーマの検証により、このオブジェクトに `owner` と `name` の引数が必要であることがわかります。

* `issues(last:20, states:CLOSED) {`

  リポジトリ内のすべての issue について説明するために、`issues` オブジェクトを呼び出します。 (単一の\_\_ クエリを`issue`で実行することも可能ですが、その場合、返したい問題の番号を把握し、引数として指定する必要があります)。

`issues` オブジェクトに関するいくつかの詳細を次に示します。

* この[ドキュメント](/ja/enterprise-server@3.22/graphql/reference/repos#object-repository)では、このオブジェクトに型 `IssueConnection` があることがわかります。

* スキーマの検証では、このオブジェクトでは引数として結果の `last` の数または `first` の数が必要であることがわかるので、`20` を指定します。

* この[ドキュメント](/ja/enterprise-server@3.22/graphql/reference/repos#object-repository)では、このオブジェクトが `states` 引数を受け入れることも示しています。これは `IssueState` または [](/ja/enterprise-server@3.22/graphql/reference/issues#enum-issuestate) の値を受け入れる `OPEN` 列挙型です。 解決された issue のみを見つけるには、`states` キーに `CLOSED` の値を指定します。

* `edges {`

`issues` 型を持っているため、`IssueConnection` は接続であることがわかります。 個々の問題に関するデータを取得するには、`edges` を使用してノードをaccessする必要があります。

* `node {`

  ここで、エッジの端にあるノードを取り出します。
  [
  `IssueConnection`このドキュメント](/ja/enterprise-server@3.22/graphql/reference/issues#object-issueconnection)では、`IssueConnection` 型の末尾にあるノードが `Issue` オブジェクトであることが示されています。

* `Issue` オブジェクトを取得することがわかっているので、[ドキュメント](/ja/enterprise-server@3.22/graphql/reference/issues#object-issue)を確認し、返すフィールドを指定できます。

  ```graphql
  title
  url
  labels(first:5) {
    edges {
      node {
        name
      }
    }
  }
  ```

  ここで、`title` オブジェクトの `url`、`labels`、`Issue` フィールドを指定します。

`labels` フィールドは型 [`LabelConnection`](/ja/enterprise-server@3.22/graphql/reference/issues#object-labelconnection) を持っています。
`issues` オブジェクトと同様に、`labels` は接続であるため、そのエッジを接続されたノード (`label` オブジェクト) に移動する必要があります。 ノードでは、返す `label` オブジェクト フィールドを指定できます。この場合は、`name` です。

Octocat のパブリック `Hello-World` リポジトリでこのクエリを実行しても、多くのラベルが返されないことに気付くかもしれません。 ラベルを使っている自分自身のリポジトリに対してこれを実行してみれば、違いがわかるでしょう。

## ミューテーションの例

ミューテーションでは、まずクエリを実行して見なければ分からない情報が必要になることがよくあります。 この例では2つの操作を示します。

1. 課題IDを取得するクエリ。
2. 絵文字のリアクションをそのIssueに追加するミューテーション。

```graphql
query FindIssueID {
  repository(owner:"octocat", name:"Hello-World") {
    issue(number:349) {
      id
    }
  }
}

mutation AddReactionToIssue {
  addReaction(input:{subjectId:"MDU6SXNzdWUyMzEzOTE1NTE=",content:HOORAY}) {
    reaction {
      content
    }
    subject {
      id
    }
  }
}
```

例を見ていきましょう。 このタスクは簡単そうです。絵文字のリアクションを課題に加えるだけです。

それでは、クエリから始めることはどのように知ることができるのでしょうか？ この時点ではまだわかりません。

サーバー上のデータを変更したい（絵文字をIssueに添付する）ので、まずは役に立つミューテーションを探してスキーマを検索することから始めます。 参照ドキュメントでは、[`addReaction`](/ja/enterprise-server@3.22/graphql/reference/reactions#mutation-addreaction) ミューテーションが、「`Adds a reaction to a subject.`」という説明とともに示されています。完璧です。

このミューテーションのドキュメントには、3つの入力フィールドがリストアップされています。

* `clientMutationId` (`String`)
* `subjectId` (`ID!`)
* `content` (`ReactionContent!`)

`!` は `subjectId` と `content` が必須フィールドであることを示します。 必須の `content` は意味があります。リアクションを追加するため、使用する絵文字を指定する必要があります。

しかし、なぜ `subjectId` が必要なのでしょうか。 これは`subjectId`がどのリポジトリのどの\_\_ 問題に対処すべきかを特定する唯一の方法だからです。

このため、この例では `ID` を取得するためのクエリから始めています。

クエリを1行ずつ調べていきましょう。

* `query FindIssueID {`

  ここではクエリを実行し、`FindIssueID` という名前を付けます。 クエリの名前付けは省略可能であることに注意してください。ここで名前を付けて、変更と同じ GUI クライアント ウィンドウに含めることができます。

* `repository(owner:"octocat", name:"Hello-World") {`

  リポジトリを指定するには、`repository` オブジェクトに対してクエリを実行し、`owner` および `name` 引数を渡します。

* `issue(number:349) {`

`issue` オブジェクトに対してクエリを実行し、`number` 引数を渡すことによって、対応する issue を指定します。

* `id`

  ここでは、`id`の`https://github.com/octocat/Hello-World/issues/349`を取得し、`subjectId`として渡します。

クエリを実行すると、`id` という `MDU6SXNzdWUyMzEzOTE1NTE=` が取得されます。

> \[!NOTE]
> クエリで返される `id` の値を、ミューテーションで `subjectID` として渡します。 ドキュメントも、スキーマのイントロスペクションでもこの関係は示されません。このことを理解するには、名前の背景となっている概念を理解しなければなりません。

IDが分かれば、ミューテーションで先に進むことができます。

* `mutation AddReactionToIssue {`

  ここではミューテーションを実行し、`AddReactionToIssue` という名前を付けます。 クエリと同様に、変更の名前付けは省略可能です。ここで名前を付けて、クエリと同じ GUI クライアント ウィンドウに含めることができます。

* `addReaction(input:{subjectId:"MDU6SXNzdWUyMzEzOTE1NTE=",content:HOORAY}) {`

  この行を調べましょう。

  * `addReaction` はミューテーションの名前です。
  * `input` は必要な引数キーです。 ミューテーションではこれは常に `input` になります。
  * `{subjectId:"MDU6SXNzdWUyMzEzOTE1NTE=",content:HOORAY}` は必要な引数の値です。 これは常に入力オブジェクト（そのため波かっこで囲まれています）であり、ミューテーション用の入力フィールド（この場合は `subjectId` と `content`）で構成されます。

  どの値がcontentとして使われるのかは、どのように分かるのでしょうか？
  [
  `addReaction`ドキュメント](/ja/enterprise-server@3.22/graphql/reference/reactions#mutation-addreaction)では、`content`フィールドに[`ReactionContent`](/ja/enterprise-server@3.22/graphql/reference/reactions#enum-reactioncontent)型があることを示しています。これは列挙型です。これは、特定の絵文字の反応のみがGitHubの問題でサポートされているためです。 リアクションとして使える値は以下のとおりです（いくつかの値は対応する絵文字の名前とは異なっていることに注意してください）。

  <table style="width:20%">
  <thead>
  <tr>
  <th scope="col" style="text-align:left">コンテンツ</th>
  <th scope="col" style="text-align:left">Emoji</th>
  </tr>
  </thead>
  <tbody>
  <tr>
  <td style="text-align:left"><code>+1</code></td>
  <td style="text-align:left">👍</td>
  </tr>
  <tr>
  <td style="text-align:left"><code>-1</code></td>
  <td style="text-align:left">👎</td>
  </tr>
  <tr>
  <td style="text-align:left"><code>laugh</code></td>
  <td style="text-align:left">😄</td>
  </tr>
  <tr>
  <td style="text-align:left"><code>confused</code></td>
  <td style="text-align:left">😕</td>
  </tr>
  <tr>
  <td style="text-align:left"><code>heart</code></td>
  <td style="text-align:left">❤️</td>
  </tr>
  <tr>
  <td style="text-align:left"><code>hooray</code></td>
  <td style="text-align:left">🎉</td>
  </tr>
  <tr>
  <td style="text-align:left"><code>rocket</code></td>
  <td style="text-align:left">🚀</td>
  </tr>
  <tr>
  <td style="text-align:left"><code>eyes</code></td>
  <td style="text-align:left">👀</td>
  </tr>
  </tbody>
  </table>

* 呼び出しの残りの部分は、ペイロードオブジェクトから構成されます。 ここでは、ミューテーションを行った後にサーバーから返してほしいデータを指定します。 これらの行は、[`addReaction` のドキュメント](/ja/enterprise-server@3.22/graphql/reference/reactions#mutation-addreaction)から取得したもので、次の 3 つの可能な戻り値フィールドがあります。

  * `clientMutationId` (`String`)
  * `reaction` (`Reaction!`)
  * `subject` (`Reactable!`)

  この例では、2 つの必須フィールド (`reaction` および`subject`) を返します。両方とも必須サブフィールド (それぞれ `content` および `id`) を持っています。

このミューテーションを実行すると、レスポンスは次のようになります。

```json
{
  "data": {
    "addReaction": {
      "reaction": {
        "content": "HOORAY"
      },
      "subject": {
        "id": "MDU6SXNzdWUyMTc5NTQ0OTc="
      }
    }
  }
}
```

これで完了です。 あなたの[問題への反応を確認します](https://github.com/octocat/Hello-World/issues/349)。:tada: をマウスオーバーしてユーザー名を見つけられます。

最後に一つ注意です。インプットオブジェクト中で複数のフィールドを渡す場合、構文が扱いにくくなることがあります。 フィールドを[変数](#working-with-variables)に移動すると役立ちます。 こちらが、オリジナルのミューテーションを変数を使って書き換える方法です。

```graphql
mutation($myVar:AddReactionInput!) {
  addReaction(input:$myVar) {
    reaction {
      content
    }
    subject {
      id
    }
  }
}
variables {
  "myVar": {
    "subjectId":"MDU6SXNzdWUyMTc5NTQ0OTc=",
    "content":"HOORAY"
  }
}
```

> \[!NOTE]
> 先ほどの例では、`content` のフィールド値 (これはミューテーション中で直接使用されます) には `HOORAY` の周りに引用符がありませんが、変数で使用される場合には引用符があることがわかります。 これには理由があります。
>
> * ミューテーションで `content` を直接使用する場合、スキーマはその値が`ReactionContent`である\_[](/ja/enterprise-server@3.22/graphql/reference/reactions#enum-reactioncontent)\_ 型であると期待し、文字列ではないとしています。 スキーマ検証は、列挙値の周りにクオートを加えるとエラーを投げます。これはクオートが文字列のために予約されているからです。
> *

`content` を変数で使用する場合、variables セクションは有効な JSON である必要があるため、引用符が必要です。 スキーマ検証では、実行中に変数がミューテーションに渡されるときに、`ReactionContent` 型が正しく解釈されます。

> 列挙型と文字列型の違いの詳細については、[公式の GraphQL 仕様](https://spec.graphql.org/June2018/#sec-Enums)に関するページを参照してください。

## 参考資料

GraphQL 呼び出しを作成する際には、もっとできることがたくさんあります。 以下は、次に見るべき場所です。

* [GraphQL API におけるページネーションの使用](/ja/enterprise-server@3.22/graphql/guides/using-pagination-in-the-graphql-api)
* [フラグメント](https://graphql.org/learn/queries/#fragments)
* [インライン フラグメント](https://graphql.org/learn/queries/#inline-fragments)
* [ディレクティブ](https://graphql.org/learn/queries/#directives)