Skip to main content

RESTからGraphQLぞの移行

GitHubのREST APIからGitHubのGraphQL APIぞの移行に関するベストプラクティスず考慮点に぀いお孊んでください。

APIのロゞックに関する差異

GitHub には、REST API ず GraphQL API ずいう 2 ぀の API が甚意されおいたす。 GitHub の API の詳现に぀いおは、「GitHub の REST API ず GraphQL API の比范」を参照しおください。

RESTからGraphQLぞの移行は、APIロゞックの倧きな倉化を瀺したす。 スタむルずしおの REST ず仕様ずしおの GraphQL ずの違いのために、REST API の呌び出しを GraphQL API のク゚リに 1 察 1 で眮き換えるこずは難しく、—しばしば望たない—結果になりたす。 移行の具䜓的な䟋を以䞋に瀺したした。

コヌドを REST API から GraphQL API に移行するには、以䞋を行いたす。

GraphQLによる重芁な利点には以䞋がありたす。

以䞋にそれぞれの䟋を瀺したす。

䟋必芁なデヌタだけを取埗

1぀のREST API呌び出しで、Organizationのメンバヌのリストを取埗したす。

curl -v https://api.github.com/orgs/:org/members

目的がメンバヌ名ずアバタヌぞのリンクの取埗だけなのであれば、このRESTのペむロヌドには過剰なデヌタが含たれおいたす。 しかし、GraphQLのク゚リでは指定した内容だけが返されたす。

query {
    organization(login:"github") {
    membersWithRole(first: 100) {
      edges {
        node {
          name
          avatarUrl
        }
      }
    }
  }
}

別の䟋を考えおみたしょう。プルリク゚ストのリストを取埗しお、それぞれがマヌゞ可胜かをチェックしたす。 REST API を呌び出すず、pull request ずその 抂芁衚珟の䞀芧が取埗されたす。

curl -v https://api.github.com/repos/:owner/:repo/pulls

pull request がマヌゞ可胜かを刀断するには、個別にそれぞれの pull request の詳现な衚珟 (倧きなペむロヌド) を取埗し、その mergeable 属性が true か false かをチェックする必芁がありたす。

curl -v https://api.github.com/repos/:owner/:repo/pulls/:number

GraphQL では、各 pull request の number 属性ず mergeable 属性のみを取埗できたす。

query {
    repository(owner:"octocat", name:"Hello-World") {
    pullRequests(last: 10) {
      edges {
        node {
          number
          mergeable
        }
      }
    }
  }
}

䟋入れ子

入れ子になったフィヌルドにク゚リを行うこずで、耇数のRESTの呌び出しを少数のGraphQLク゚リに眮き換えられたす。 たずえば、REST API を䜿っお、コミット、非レビュヌ コメント、レビュヌず䞀緒に pull request を取埗するには、4 ぀の別々の呌び出しが必芁になりたす。

curl -v https://api.github.com/repos/:owner/:repo/pulls/:number
curl -v https://api.github.com/repos/:owner/:repo/pulls/:number/commits
curl -v https://api.github.com/repos/:owner/:repo/issues/:number/comments
curl -v https://api.github.com/repos/:owner/:repo/pulls/:number/reviews

GraphQL API を䜿えば、入れ子のフィヌルドを利甚しお単䞀のク゚リでこのデヌタを取埗できたす。

{
  repository(owner: "octocat", name: "Hello-World") {
    pullRequest(number: 1) {
      commits(first: 10) {
        edges {
          node {
            commit {
              oid
              message
            }
          }
        }
      }
      comments(first: 10) {
        edges {
          node {
            body
            author {
              login
            }
          }
        }
      }
      reviews(first: 10) {
        edges {
          node {
            state
          }
        }
      }
    }
  }
}

pull request 番号の 倉数を眮き換えるこずで、このク゚リの機胜を拡匵するこずもできたす。

䟋匷力な型付け

GraphQLスキヌマは匷く型付けされおおり、デヌタの扱いが安党になっおいたす。

GraphQL ミュヌテヌションを䜿甚しお問題たたは pull request にコメントを远加し、clientMutationId の倀に文字列ではなく敎数を誀っお指定する䟋を考えおみたしょう。

mutation {
  addComment(input:{clientMutationId: 1234, subjectId: "MDA6SXNzdWUyMjcyMDA2MTT=", body: "Looks good to me!"}) {
    clientMutationId
    commentEdge {
      node {
        body
        repository {
          id
          name
          nameWithOwner
        }
        issue {
          number
        }
      }
    }
  }
}

このク゚リを実行するず、この操䜜に期埅される型を指定した゚ラヌが返されたす。

{
  "data": null,
  "errors": [
    {
      "message": "Argument 'input' on Field 'addComment' has an invalid value. Expected type 'AddCommentInput!'.",
      "locations": [
        {
          "line": 3,
          "column": 3
        }
      ]
    },
    {
      "message": "Argument 'clientMutationId' on InputObject 'AddCommentInput' has an invalid value. Expected type 'String'.",
      "locations": [
        {
          "line": 3,
          "column": 20
        }
      ]
    }
  ]
}

クオヌトで 1234 をラップするず、この倀を敎数倀から期埅されおいる型である文字列に倉換できたす。

mutation {
  addComment(input:{clientMutationId: "1234", subjectId: "MDA6SXNzdWUyMjcyMDA2MTT=", body: "Looks good to me!"}) {
    clientMutationId
    commentEdge {
      node {
        body
        repository {
          id
          name
          nameWithOwner
        }
        issue {
          number
        }
      }
    }
  }
}