GraphQL APIクエリと変異の実行

このガイドはGitLab GraphQL APIの基本的な使い方を示します。

API自体の開発に取り組みたい開発者を対象とした実装の詳細については、GraphQL APIスタイルガイドをお読みください。

実行例

ここに記載されている例は、以下の方法で実行できます:

コマンドライン

GraphQLクエリは、ローカルコンピューター上のコマンドラインでcurl リクエストとして実行できます。GraphQL リクエストは、クエリをペイロードとして/api/graphql へのPOST リクエストとして作成できます。ベアラートークンとして使用するパーソナルアクセストークンを生成することで、リクエストを作成者に認証させることができます。このトークンには少なくともread_api スコープが必要です。

使用例:

GRAPHQL_TOKEN=<your-token>
curl "https://gitlab.com/api/graphql" --header "Authorization: Bearer $GRAPHQL_TOKEN" \
     --header "Content-Type: application/json" --request POST \
     --data "{\"query\": \"query {currentUser {name}}\"}"

クエリー文字列の中に文字列を入れ子にするには、データをシングルクォートで囲むか、文字列を\\ でエスケープします:

curl "https://gitlab.com/api/graphql" --header "Authorization: Bearer $GRAPHQL_TOKEN" \
    --header "Content-Type: application/json" --request POST \
    --data '{"query": "query {project(fullPath: \"<group>/<subgroup>/<project>\") {jobs {nodes {id duration}}}}"}'
      # or "{\"query\": \"query {project(fullPath: \\\"<group>/<subgroup>/<project>\\\") {jobs {nodes {id duration}}}}\"}"

GraphiQL

GraphiQL (「グラフィカル」と発音します) を使用すると、構文の強調表示やオートコンプリートを使用して、サーバーのエンドポイントに対して直接クエリを実行できます。また、スキーマや型を探索することもできます。

以下の例を参照してください:

  • GitLab に対して直接実行できます。
  • GitLab.comに対して追加設定なしで動作します。サインインしていることを確認し、GraphiQL Explorerに移動してください。

クエリをローカルまたはセルフマネージドインスタンスで実行したい場合は、以下のいずれかを行う必要があります:

  • gitlab-org グループを作成し、その下にgraphql-sandbox というプロジェクトを作成します。プロジェクト内に複数のイシューを作成します。
  • クエリを編集して、gitlab-org/graphql-sandbox を自分のグループとプロジェクトに置き換えてください。

詳細については、GraphiQLの実行を参照してください。

note
GitLab 12.0を実行している場合は、graphql 機能フラグを有効にしてください。

Railsコンソール

GraphQLクエリはRailsコンソールセッションで実行できます。たとえば、プロジェクトを検索する場合などです:

current_user = User.find_by_id(1)
query = <<~EOQ
query securityGetProjects($search: String!) {
  projects(search: $search) {
    nodes {
      path
    }
  }
}
EOQ

variables = { "search": "gitlab" }

result = GitlabSchema.execute(query, variables: variables, context: { current_user: current_user })
result.to_h

クエリとミューテーション

GitLab GraphQL API を使って実行することができます:

  • データ検索のためのクエリ。
  • データの作成、更新、削除のための変異
note
GitLab GraphQL API では、idグローバル IDを指し、"gid://gitlab/Issue/123"の形式のオブジェクト識別子です。

GitLab GraphQL スキーマは、クライアントがクエリ可能なオブジェクトとフィールド、および対応するデータ型の概要を示しています。

例現在認証されているユーザーがグループgitlab-org でアクセスできる(上限がある)すべてのプロジェクトの名前のみを取得します。

query {
  group(fullPath: "gitlab-org") {
    id
    name
    projects {
      nodes {
        name
      }
    }
  }
}

例特定のプロジェクトとイシュー#2のタイトルを取得します。

query {
  project(fullPath: "gitlab-org/graphql-sandbox") {
    name
    issue(iid: "2") {
      title
    }
  }
}

グラフの走査

子ノードを取得する場合は

  • edges { node { } } 構文を使用します。
  • 短縮形nodes { } 構文。

その下にあるのが、私たちがトラバースしているグラフであり、それがGraphQLという名前の由来です。

例プロジェクト名とそのすべてのイシューのタイトルを取得します。

query {
  project(fullPath: "gitlab-org/graphql-sandbox") {
    name
    issues {
      nodes {
        title
        description
      }
    }
  }
}

クエリの詳細:GraphQLドキュメント

作成者

認証はGitLabアプリケーション(およびGitLab.com)と同じエンジンを使用します。GitLabにサインインしてGraphiQLを使用している場合、すべてのクエリは認証されたユーザーとして実行されます。詳細については、GitLab API ドキュメントをお読みください。

突然変異

突然変異はデータに変更を加えます。レコードの更新、削除、新規作成が可能です。ミューテーションは通常、InputTypesと変数を使用します。

ミューテーションには

  • 入力。例えば、どの絵文字リアクションをどのオブジェクトに追加するかといった引数です。
  • リターンステートメント。つまり、成功したときに何を返したいかです。
  • エラー。念のため、何が間違っていたのかを常に尋ねてください。

創造の突然変異

例お茶を飲もう -:tea: リアクションの絵文字をイシューに追加します。

mutation {
  awardEmojiAdd(input: { awardableId: "gid://gitlab/Issue/27039960",
      name: "tea"
    }) {
    awardEmoji {
      name
      description
      unicode
      emoji
      unicodeVersion
      user {
        name
      }
    }
    errors
  }
}

例イシューにコメントを追加します。この例では、GitLab.com のイシューのIDを使用します。ローカル・インスタンスを使用している場合は、書き込み可能なイシューのIDを取得する必要があります。

mutation {
  createNote(input: { noteableId: "gid://gitlab/Issue/27039960",
      body: "*sips tea*"
    }) {
    note {
      id
      body
      discussion {
        id
      }
    }
    errors
  }
}

変異の更新

作成したノートの結果id が表示されたら、メモを取りましょう。より速くすするために編集しましょう。

mutation {
  updateNote(input: { id: "gid://gitlab/Note/<note ID>",
      body: "*SIPS TEA*"
    }) {
    note {
      id
      body
    }
    errors
  }
}

欠失変異

お茶がなくなっちゃったので、コメントを削除しましょう。

mutation {
  destroyNote(input: { id: "gid://gitlab/Note/<note ID>" }) {
    note {
      id
      body
    }
    errors
  }
}

以下のような出力が得られるはずです:

{
  "data": {
    "destroyNote": {
      "errors": [],
      "note": null
    }
  }
}

ノートの詳細を尋ねましたが、もう存在しないので、null

変異の詳細:GraphQLドキュメント

プロジェクト設定の更新

1回のGraphQL変異で複数のプロジェクト設定を更新できます。この例は、CI_JOB_TOKEN スコープ動作の大きな変更に対する回避策です。

mutation DisableCI_JOB_TOKENscope {
  projectCiCdSettingsUpdate(input:{fullPath: "<namespace>/<project-name>", inboundJobTokenScopeEnabled: false, jobTokenScopeEnabled: false}) {
    ciCdSettings {
      inboundJobTokenScopeEnabled
      jobTokenScopeEnabled
    }
    errors
  }
}

イントロスペクティブクエリ

クライアントは、イントロスペクティブ・クエリを実行することで、自身のスキーマに関する情報を GraphQL エンドポイントにクエリできます。GraphiQL クエリ・エクスプローラーはイントロスペクティブ・クエリを使用します:

  • GraphQL スキーマに関する知識を得ます。
  • オートコンプリートを実行します。
  • インタラクティブなDocs タブを提供します。

例スキーマ内のすべての型名を取得します。

{
  __schema {
    types {
      name
    }
  }
}

例Issue に関連するすべてのフィールドを取得します。kind は、OBJECTSCALARINTERFACE のように、型の enum 値を示します。

query IssueTypes {
  __type(name: "Issue") {
    kind
    name
    fields {
      name
      description
      type {
        name
      }
    }
  }
}

イントロスペクションの詳細GraphQLドキュメント

クエリの複雑さ

算出されたクエリの複雑さのスコアと上限はqueryComplexity をクエリすることでクライアントに公開することができます。

query {
  queryComplexity {
    score
    limit
  }

  project(fullPath: "gitlab-org/graphql-sandbox") {
    name
  }
}

ソート

GitLab GraphQLエンドポイントのいくつかでは、オブジェクトのコレクションをどのようにソートするかを指定することができます。スキーマが許すものでしかソートできません。

例イシューは作成日でソートできます:

query {
  project(fullPath: "gitlab-org/graphql-sandbox") {
   name
    issues(sort: created_asc) {
      nodes {
        title
        createdAt
      }
    }
  }
}

ページネーション

ページネーションとは、レコードの一部、例えば最初の10件だけを要求する方法です。より多くのレコードが必要な場合は、please give me the next ten records のような形式で次の10件をサーバにリクエストします。

デフォルトでは、GitLab GraphQL API はページあたり 100 件のレコードを返します。この動作を変更するには、first またはlast 引数を使用します。どちらの引数も値を取るので、first: 10 は最初の 10 レコード、last: 10 は最後の 10 レコードを返します。ページごとに返されるレコード数には制限があり、通常は100です。

例最初の2つのイシューのみを取得します(スライシング)。cursor フィールドは、そのレコードに関連する他のレコードを取得できる位置を示します。

query {
  project(fullPath: "gitlab-org/graphql-sandbox") {
    name
    issues(first: 2) {
      edges {
        node {
          title
        }
      }
      pageInfo {
        endCursor
        hasNextPage
      }
    }
  }
}

例次の3件を取得します。(カーソル値eyJpZCI6IjI3MDM4OTMzIiwiY3JlYXRlZF9hdCI6IjIwMTktMTEtMTQgMDU6NTY6NDQgVVRDIn0 は異なる可能性がありますが、上記で返された2番目のイシューに対して返されたcursor の値です)

query {
  project(fullPath: "gitlab-org/graphql-sandbox") {
    name
    issues(first: 3, after: "eyJpZCI6IjI3MDM4OTMzIiwiY3JlYXRlZF9hdCI6IjIwMTktMTEtMTQgMDU6NTY6NDQgVVRDIn0") {
      edges {
        node {
          title
        }
        cursor
      }
      pageInfo {
        endCursor
        hasNextPage
      }
    }
  }
}

ページネーションとカーソルの詳細:GraphQLドキュメント