跳至主要内容

从 REST 迁移到 GraphQL

了解从 GitHub 的 REST API 迁移到 GitHub 的 GraphQL API 的最佳实践和注意事项。

API 逻辑的差异

GitHub 提供了两个 API:REST API 和 GraphQL API。欲了解更多关于 GitHub API 的信息,请参阅 比较 GitHub 的 REST API 与 GraphQL API

从 REST 迁移到 GraphQL 是 API 逻辑的重大转变。REST 作为一种风格与 GraphQL 作为规范之间的差异,使得在一对一基础上用 GraphQL 查询替换 REST 调用既困难且常常不合适。以下我们提供了具体的迁移示例。

将代码从 REST API 迁移到 GraphQL API

GraphQL 的主要优势包括

以下是每个示例。

示例:仅获取所需数据,不多余

一次 REST API 调用即可检索组织成员列表

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

如果目标仅获取成员姓名和头像链接,REST 的响应会包含过多数据。而 GraphQL 查询只返回您指定的内容

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

再举一个例子:获取拉取请求列表并检查每个是否可合并。对 REST API 的调用会返回拉取请求列表及其 概要表示

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

要判断拉取请求是否可合并,需要单独检索每个拉取请求的 详细表示(负载较大),并检查其 mergeable 属性是 true 还是 false

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

使用 GraphQL,您可以仅检索每个拉取请求的 numbermergeable 属性

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

示例:嵌套

使用嵌套字段查询可以用更少的 GraphQL 查询替代多个 REST 调用。例如,使用 REST API 检索拉取请求及其提交、非审查评论和审查需要四次独立调用

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
          }
        }
      }
    }
  }
}

您还可以通过 使用变量 替换拉取请求编号,进一步增强查询的灵活性。

示例:强类型

GraphQL 架构是强类型的,使数据处理更安全。

考虑一个使用 GraphQL mutation 为议题或拉取请求添加评论的示例,若错误地为 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
        }
      }
    }
  }
}
© . This site is unofficial and not affiliated with GitHub, Inc.