GraphQL

By Amitosh Swain Mahapatra

Published on

GraphQL is a query language which allows clients specify what data is required, and exactly the same structure of the data is returned from the server. It provides an excellent alternative to traditional REST API designs. Depeloped internally and subsequently released publicly by Facebook, it is now being increasingly used in many websites such as Github.

Background

REST seems like the responses simultaneously send too much data, yet do not include data that client needs.

While working with Github Integration for my GSoC Project at FOSSi Foundation, I started with v3 of Github API. It was familiar REST API which we all have been using since long. But soon I realized the problem with REST. Github has a rate-limit on number of API calls per hour, and with using REST, we needed ~10 calls to fetch just the metadata. The responses were huge, mostly containing data not needed by us, while still not providing all the data we need.

Using GraphQL

GraphQL requests are POST requests to the GraphQL endpoint and the response is returned as JSON.

A GraphQL request to an endpoint can be a query or a mutation. At its simplest form, a GraphQL query specifies the fields to return, and the server responds with a repoonse matching the query. For example, we use GraphQL to extract owner info, stars, forks, pulls-requests and issue statistics using GraphQL with a query like this:

{
  repository(owner: "librecores", name: "librecores-web") {
      nameWithOwner
      name
      owner {
        login
        avatarUrl
      }
      stargazers {
        totalCount
      }
      forks {
        totalCount
      }
      watchers {
        totalCount
      }
      issues(states: [OPEN]) {
        totalCount
      }
      description
      license
  }
}

And the server returns a response like this:

{
  "data": {
    "repository": {
      "nameWithOwner": "librecores/librecores-web",
      "name": "librecores-web",
      "owner": {
        "login": "librecores",
        "avatarUrl": "https://avatars5.githubusercontent.com/u/10119298?v=4"
      },
      "stargazers": {
        "totalCount": 11
      },
      "forks": {
        "totalCount": 5
      },
      "watchers": {
        "totalCount": 14
      },
      "issues": {
        "totalCount": 39
      },
      "description": "LibreCores Web Site",
      "license": "Other"
    }
  }
}

You can try this query in the Github GraphQL explorer

A mutation, on the otherhand, changes the value of something. For example, programmatically adding a comment to an issue will require a mutate query. You can read more about GraphQL queries in their official documentation.

Using GraphQL in Github API v4 has enabled us to easily extract required metrics in a single API call. My work on Github API is a part of a pull request to librecores/librecores-web. You can check it on Github.