Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Learn best practices and considerations for migrating from GitHubScope's REST API to GitHubScope's GraphQL API.

In this article

...

Differences in API logic

...

Example: Getting the data you need and nothing more

...

Example: Nesting

...

Table of Contents

Differences in API logic

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 to the REST API to the GraphQL API:

  • Review the GraphQL the GraphQL spec

  • Review GitHubScope's GraphQL schema

  • Consider how any existing code you have currently interacts with the GitHub Scope REST API

  • Use Global Node IDs to reference objects between API versions

Significant advantages of GraphQL include:

Here are examples of each.

Example #1: Getting the data you need, and nothing more

A single REST API call retrieves a list of your organization's members:

Code Block
curl -v https://apicms.githubscopear.com/orgsapi/:orgv2/membersusers

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:

Code Block
query {
    organization(login:"github")viewer {
    membersWithRole(first: 100) {organization {
       edgesmembers(first: 10) {
        nodeedges {
          namenode  {
        avatarUrl    name
    }       }
    }
  }
}

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:

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

Determining if a pull request is mergeable requires retrieving each pull request individually for its detailed representation (a large payload) and checking whether its mergeable attribute is true or false:

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

With GraphQL, you could retrieve only the number and mergeable attributes for each pull request:

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

Example #2: Nesting

Querying with nested fields lets you replace multiple REST calls with fewer GraphQL queries. For example, retrieving a pull request scenario along with its commits, non-review comments, and reviews ar contents and associated groups using the REST API requires four separate calls:

Code Block
curl -v https://apicms.githubscopear.com/reposapi/:ownerv2/:repo/pullsscenarios/:numberid
curl -v https://apicms.githubscopear.com/reposapi/:ownerv2/:reposcenarios/pulls/:numberid/commitsattachments
curl -v https://apicms.githubscopear.com/reposapi/:ownerv2/:reposcenarios/issues/:numberid/commentsauthoring_groups
curl -v https://apicms.githubscopear.com/reposapi/:ownerv2/:reposcenarios/pulls/:numberid/reviewsgroups

Using the GraphQL API, you can retrieve the data with a single query using nested fields:

Code Block
{
  repositorynode(ownerid: "octocat", name: "Hello-WorldID_OF_SCENARIO")
{     pullRequest(number: 1) {... on Scenario
      name
commits(first: 10) {      content   edges {
        fileUrl
 node {      fileContentType
      commit {
              oid
              message
   fileUrlExpiresAt
         }
          }
        }
      }
      comments(first: 10) groups {
        edges {
          node nodes {          
  body        id
    author {     name
         login
            }
 
        }
        }
      }
      reviews(first: 10) {
        edges {
          node {
            state
          }
        }
      }
    }
  }
}

You can also extend the power of this query by substituting by substituting a variable for variable for the pull request number.

Example #3: Strong typing

GraphQL schemas are strongly typed, making data handling safer.

Consider an example of adding a comment to an issue or pull request renaming a scenario using a GraphQL mutationGraphQL mutation, and mistakenly specifying an integer rather than a string for the value of clientMutationIdname:

Code Block
mutation {
  addComment(input:{clientMutationIdupdateScenario(id: 1234, subjectId: "MDA6SXNzdWUyMjcyMDA2MTT=", bodyinput:{name: "Looks good to me!"1234}) {
    clientMutationIdid
    commentEdgename
{    groups   node {
      nodes { body         repository
{           id
 
        name
          nameWithOwner
        }
        issue {
          number
        }
      }
    }

 }
}

Executing this query returns errors specifying the expected types for the operation:

Code Block
{
  "data": null,
  "errors": [
    {
      "message": "Argument 'input' on Field 'addCommentname' has an invalid value. Expected type 'AddCommentInputString!'.",
      "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:

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