1
0
mirror of synced 2025-12-19 18:10:59 -05:00
Files
docs/content/graphql/guides/migrating-from-rest-to-graphql.md

219 lines
6.2 KiB
Markdown

---
title: Migrating from REST to GraphQL
intro: 'Learn best practices and considerations for migrating from {% data variables.product.prodname_dotcom %}''s REST API to {% data variables.product.prodname_dotcom %}''s GraphQL API.'
redirect_from:
- /v4/guides/migrating-from-rest
- /graphql/guides/migrating-from-rest
versions:
fpt: '*'
ghec: '*'
ghes: '*'
topics:
- API
shortTitle: Migrate from REST to GraphQL
---
## Differences in API logic
{% data variables.product.company_short %} provides two APIs: a REST API and a GraphQL API. For more information about {% data variables.product.company_short %}'s APIs, see [AUTOTITLE](/rest/overview/about-githubs-apis).
Migrating from REST to GraphQL represents a significant shift in API logic. The differences between REST as a style and GraphQL as a specification make it difficult—and often undesirable—to replace REST API calls with GraphQL API queries on a one-to-one basis. We've included specific examples of migration below.
To migrate your code from the [REST API](/rest) to the GraphQL API:
* Review the [GraphQL spec](https://spec.graphql.org/June2018/)
* Review GitHub's [GraphQL schema](/graphql/reference)
* Consider how any existing code you have currently interacts with the GitHub REST API
* Use [Global Node IDs](/graphql/guides/using-global-node-ids) to reference objects between API versions
Significant advantages of GraphQL include:
* [Getting the data you need and nothing more](#example-getting-the-data-you-need-and-nothing-more)
* [Nested fields](#example-nesting)
* [Strong typing](#example-strong-typing)
Here are examples of each.
## Example: Getting the data you need and nothing more
A single REST API call retrieves a list of your organization's members:
```shell
curl -v {% data variables.product.rest_url %}/orgs/:org/members
```
The REST payload contains excessive data if your goal is to retrieve only member names and links to avatars. However, a GraphQL query returns only what you specify:
```graphql
query {
organization(login:"github") {
membersWithRole(first: 100) {
edges {
node {
name
avatarUrl
}
}
}
}
}
```
Consider another example: retrieving a list of pull requests and checking if each one is mergeable. A call to the REST API retrieves a list of pull requests and their [summary representations](/rest#summary-representations):
```shell
curl -v {% data variables.product.rest_url %}/repos/:owner/:repo/pulls
```
Determining if a pull request is mergeable requires retrieving each pull request individually for its [detailed representation](/rest#detailed-representations) (a large payload) and checking whether its `mergeable` attribute is true or false:
```shell
curl -v {% data variables.product.rest_url %}/repos/:owner/:repo/pulls/:number
```
With GraphQL, you could retrieve only the `number` and `mergeable` attributes for each pull request:
```graphql
query {
repository(owner:"octocat", name:"Hello-World") {
pullRequests(last: 10) {
edges {
node {
number
mergeable
}
}
}
}
}
```
## Example: Nesting
Querying with nested fields lets you replace multiple REST calls with fewer GraphQL queries. For example, retrieving a pull request along with its commits, non-review comments, and reviews using the **REST API** requires four separate calls:
```shell
curl -v {% data variables.product.rest_url %}/repos/:owner/:repo/pulls/:number
curl -v {% data variables.product.rest_url %}/repos/:owner/:repo/pulls/:number/commits
curl -v {% data variables.product.rest_url %}/repos/:owner/:repo/issues/:number/comments
curl -v {% data variables.product.rest_url %}/repos/:owner/:repo/pulls/:number/reviews
```
Using the **GraphQL API**, you can retrieve the data with a single query using nested fields:
```graphql
{
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
}
}
}
}
}
}
```
You can also extend the power of this query by [substituting a variable](/graphql/guides/forming-calls-with-graphql#working-with-variables) for the pull request number.
## Example: Strong typing
GraphQL schemas are strongly typed, making data handling safer.
Consider an example of adding a comment to an issue or pull request using a GraphQL [mutation](/graphql/reference/mutations), and mistakenly specifying an integer rather than a string for the value of [`clientMutationId`](/graphql/reference/mutations#addcomment):
```graphql
mutation {
addComment(input:{clientMutationId: 1234, subjectId: "MDA6SXNzdWUyMjcyMDA2MTT=", body: "Looks good to me!"}) {
clientMutationId
commentEdge {
node {
body
repository {
id
name
nameWithOwner
}
issue {
number
}
}
}
}
}
```
Executing this query returns errors specifying the expected types for the operation:
```json
{
"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
}
]
}
]
}
```
Wrapping `1234` in quotes transforms the value from an integer into a string, the expected type:
```graphql
mutation {
addComment(input:{clientMutationId: "1234", subjectId: "MDA6SXNzdWUyMjcyMDA2MTT=", body: "Looks good to me!"}) {
clientMutationId
commentEdge {
node {
body
repository {
id
name
nameWithOwner
}
issue {
number
}
}
}
}
}
```