GitHub Reaccs - Trying GraphQL with GitHub's APIv4

5 minute read Published: 2020-05-20

Motivation

A few weeks ago, I had the idea of writing a small script to collect reaction data for a given user's isses, pull requests, and comments on GitHub. I thought it would be a fun meme for my friends and I who are active in the open source community - there's nothing better than when someone hits you with a "LGTM" and 🚀 reaction on your PR. Who wouldn't want to see a history of all those (hopefully positive) reactions?

I set out initially to make the script in Go using the GitHub REST APIv3. This proved to be challenging, as the API did not have direct endpoints for reaction data and making nested calls to associate a user with a comment was not straightforward. I pivoted to thinking I could write a nice webcrawler in Go since Go is suited for solving problems of concurrency and a webcrawler is even an excercise in the tour of Go1. I ended up coming up with a small webcrawler, but it wasn't as fast as I would have hoped and I never quite fully implemented it, which caused me to put this little project on the backburner.

Why GraphQL over the REST API?

Recently, I was introduced to GraphQL by a friend whose company had started converting their existing APIs from REST to GraphQL. GraphQL is a "query language for your API". It allows users to explicitly ask for the data they want, which includes types and amounts of specific information. I began to play around with it and read through some of the documentation. In reading more about GraphQL, I stumbled upon GitHub's APIv4, which is implemented in GraphQL. This inspired me to pick up this project again as the goal of collecting such information about a GitHub user became much easier.

A query for GraphQL allows you to easier visualize relationships between data and access that data as you please. Whereas my initial implementation with the REST API took many dependent, consecutive requests, www.ghreaccs.com involves only a single GraphQL query:

user(login: "${username}") {
    issueComments(last: 100) {
        nodes {
            reactions(last: 100){
                nodes{
                    content
                    }
            }
        }
    }
    pullRequests(last: 100) {
        nodes{
            reactions(last: 100){
                nodes{
                    content
                }
            }
        }
    }
    issues(last: 100) {
        nodes{
            reactions(last: 100){
                nodes{
                    content
                }
            }
        }
    }
}

I think this query demonstrates the use cases of GraphQL for a few reasons. One is of course the amount of information returned from a single query. In what would have been requests to multiple REST API endpoints, a GraphQL query such as the one above can return all the information you would like in one request. For example, I could have expanded upon this query and requested other data about comments, issues, and PRs such as the date posted, the text, related posts in the same issue/PR thread, etc. All this could be done with just adding a few lines to the query - no need for hitting separate endpoints. The other use case, related to simplifying a request, is performance. Since GraphQL treats data as objects which have relationships with one another, it is much faster to find relationships between objects in this case using a GraphQL API vs. a REST API.

ghreaccs

ghreaccs is a simple React app that finds reactions to your GitHub issues, PRs, and comments using GitHub's GraphQL APIv4. You can try it out at https://www.ghreaccs.com and view the code at https://github.com/ginglis13/ghreaccs.

If you don't want to use my site, you can run the query yourself in GitHub's query builder: https://developer.github.com/v4/explorer/2

As you can see, I had to explicitly ask for the last 100 comments, PRs, issues, and the last 100 reactions on each of these. This is due to the way GitHub handles rate limitations with APIv4, which, since this is a GraphQL API, are actually resource limitations.

Since it's probably obvious I'm not the best frontend developer, feel free to make this site better by opening an issue or PR ( I'll probably react to your issue/pr and you can see it update on the site! 😄).

This was a fun intro to GraphQL and React for me, as I had very minimal experience with both prior to this. I will definitely start considering the advantages and disadvantages of using REST vs. GraphQL in future work and projects.



1I Highly recommend A Tour of Go to anyone looking to learn Go! https://tour.golang.org/concurrency/10
2You will need to make your own personal access token to use the query builder.