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

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

...

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:"githubScope") {
    membersWithRolemembers(first: 10010) {
      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:

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
queryavatar { 
   repository(owner:"octocat", name:"Hello-World") {     pullRequests(last: 10) {
   fileUrl
   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 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/api/v2/repos/:ownerscenarios/:repo/pulls/:numberid
curl -v https://apicms.githubscopear.com/api/v2/repos/:ownerscenarios/:repo/pulls/:number/commitsid/attachments
curl -v https://apicms.githubscopear.com/api/v2/repos/:ownerscenarios/:repo/issues/:number/commentsid/authoring_groups
curl -v https://apicms.githubscopear.com/api/v2/repos/:ownerscenarios/:repo/pulls/:number/reviewsid/groups

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 {
          nodefileUrl
{        fileContentType
    commit {               oid
              message
   fileUrlExpiresAt
        }
          }
        }
      }
      comments(first: 10) groups {
        edgesnodes {
          node
{          id
  body             author {
              login
            }
          }
        }
      }
      reviews(first: 10) {
        edges {
          node {
            state
          }name
        }
      }
    }
  }
}

You can also extend the power of this query by substituting by substituting a variable for variable 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 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:{clientMutationId: 1234, subjectIdupdateScenario(id: "MDA6SXNzdWUyMjcyMDA2MTT=", bodyinput:{name: "Looks good to me!"1234}) {
    clientMutationIdid
    commentEdge {name
      nodegroups {
      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
        }
      }
    }
  }
}