{"id":16521,"date":"2017-03-10T12:15:49","date_gmt":"2017-03-10T10:15:49","guid":{"rendered":"https:\/\/www.webcodegeeks.com\/?p=16521"},"modified":"2017-03-09T16:29:38","modified_gmt":"2017-03-09T14:29:38","slug":"introduction-graphql-via-github-api","status":"publish","type":"post","link":"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/","title":{"rendered":"An Introduction to GraphQL via the GitHub API"},"content":{"rendered":"<p>RESTful, JSON-delivering APIs are today\u2019s default choice when building an API. However, there\u2019s a new API kid on the block that\u2019s generating considerable attention: <a href=\"http:\/\/graphql.org\/\">GraphQL<\/a>.<\/p>\n<p>GraphQL is an entirely new way to consume and build APIs. Done right, you can build wonderfully tight integrations that aren\u2019t possible with REST APIs. Today, we\u2019ll get firsthand exposure to GraphQL via the GitHub GraphQL API.<\/p>\n<p>Before we start coding, let\u2019s explore why companies like GitHub, Facebook, and Pinterest are releasing GraphQL APIs.<\/p>\n<h2>The Origins of GraphQL<\/h2>\n<p>In 2012, Facebook began an effort to rebuild their native mobile apps and quickly ran into a major source of frustration.<\/p>\n<p>The Facebook mobile team required a JSON version of the news feed so it could be rendered with native components. However, there were significant differences between how the news feed data was <em>stored<\/em> and how product designers and developers <em>consumed<\/em> that data.<\/p>\n<p>Frequently, developers like me think of data as a graph of objects. For example, I might represent the data presented on the Codeship blog like this:<\/p>\n<pre class=\"brush:php\">blog(name: 'codeship') {\r\n  title\r\n  feedUrl\r\n  posts(last: 10) {\r\n    title\r\n    url\r\n    commentsCount\r\n    favorites {\r\n      id\r\n      avatar_url\r\n    }\r\n  }\r\n}<\/pre>\n<p>However, data is typically not query-able \u2014 much less stored \u2014 in an easy-to-consume graph format. If the data is available in a REST API, it may require multiple API calls (for example, a separate HTTP call to fetch comment details for every post rendered on the page). Additionally, I can rarely specify <em>only<\/em> the data I need with a REST API: Instead, I\u2019ll typically get a dump of <em>everything<\/em> available for each record.<\/p>\n<p>Multiple HTTP calls? Sending excessive amounts of data across the wire? These are huge burdens when you want to deliver fast-responding interactions. On mobile \u2014 which was Facebook\u2019s focus \u2014 these problems are compounded.<\/p>\n<p>To solve this problem, Facebook\u2019s engineering team <a href=\"https:\/\/code.facebook.com\/posts\/1691455094417024\/graphql-a-data-query-language\/\">developed GraphQL<\/a>. GraphQL approaches data-fetching from the perspective of product designers and developers.<\/p>\n<h2>Enter GraphQL<\/h2>\n<p>After three years of internal use, Facebook released a working draft of the GraphQL spec in 2015. APIs that conform to this spec can be queried via a graph syntax similar to the sample above. The server-side runtime for executing GraphQL queries doesn\u2019t tie you to a particular storage engine: It\u2019s an application-level API, not a database.<\/p>\n<p>Today, companies like GitHub, Pinterest, and Shopify have released GraphQL APIs.<\/p>\n<h2>What Problems Does GraphQL Solve Versus REST?<\/h2>\n<p>These are the some of the key GraphQL features and the problems they solve:<\/p>\n<ol>\n<li><strong>Get exactly what you ask for:<\/strong> Your queries mirror the shape of data returned from a GraphQL API, so there\u2019s no confusion over which fields an API call returns.<\/li>\n<li><strong>Nesting:<\/strong> Graph queries can be nested, so you can fetch data across relationships. Without GraphQL, gathering data across relationships typically involves multiple, slower, HTTP calls.<\/li>\n<li><strong>Strongly typed:<\/strong> It\u2019s important to get the data format you expect when working with an external data source. GraphQL is strongly typed, so you get these guarantees.<\/li>\n<li><strong>Introspective:<\/strong> Since a GraphQL server can be queried for the calls it supports, you can use tools like GraphiQL to organically explore versus hunting through API docs.<\/li>\n<li><strong>No versioning:<\/strong> Since you get what ask for, fields won\u2019t be added or removed out from under you. When fields are deprecated, they can be marked as such to provide advance warning.<\/li>\n<\/ol>\n<h2>Let\u2019s Solve a Problem with GraphQL<\/h2>\n<p>Let\u2019s say I have an idea for a GitHub integration: Given a specific GitHub repository, maintain a leader board of which developers are most active commenting on pull requests.<\/p>\n<p>The output should look like:<\/p>\n<p><code>+--------------------------+----------+<br \/>\n| Author | Comments |<br \/>\n+--------------------------+----------+<br \/>\n| Richard | 65 |<br \/>\n| Derek | 23 |<br \/>\n| Josh | 21 |<br \/>\n| ... | ... |<br \/>\n+--------------------------+----------+<\/code><\/p>\n<h3>Set up your GraphQL environment<\/h3>\n<p>We\u2019ll get things going on the GitHub side (sign up for early access and generate an access token) and install <a href=\"https:\/\/github.com\/skevy\/graphiql-app\">GraphiQL.app<\/a>, a GraphQL query editor.<\/p>\n<h2>Sign up with GitHub\u2019s early access program<\/h2>\n<p>The GitHub\u2019s GraphQL library is in their <a href=\"https:\/\/developer.github.com\/early-access\/\">early access program<\/a>, which requires acknowledgment to join. <a href=\"https:\/\/github.com\/prerelease\/agreement\">Accept the prerelease agreement<\/a> to sign up.<\/p>\n<h2>Generate a GitHub personal access token<\/h2>\n<p>We will authenticate to GitHub\u2019s GraphQL API via a personal access token. <a href=\"https:\/\/help.github.com\/articles\/creating-an-access-token-for-command-line-use\/\">Follow the steps<\/a> in the GitHub guide, enabling the following scopes:<\/p>\n<p><a href=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/scopes.png\"><img decoding=\"async\" class=\"aligncenter wp-image-16524\" src=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/scopes.png\" width=\"860\" height=\"576\" srcset=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/scopes.png 1542w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/scopes-300x201.png 300w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/scopes-768x514.png 768w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/scopes-1024x685.png 1024w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<p>Copy the generated access token to your clipboard.<\/p>\n<h2>Install GraphiQL.app<\/h2>\n<p><a href=\"https:\/\/github.com\/skevy\/graphiql-app\">GraphiQL.app<\/a> is a lightweight wrapper around <a href=\"https:\/\/github.com\/graphql\/graphiql\">GraphiQL<\/a>, an interactive in-browser IDE for GraphQL. GraphiQL makes it easy to explore GraphQL APIs like GitHub\u2019s.<\/p>\n<p><a href=\"https:\/\/github.com\/skevy\/graphiql-app\/blob\/master\/README.md\">View the GraphiQL.app README<\/a> for installation instructions.<\/p>\n<h2>Configure GraphiQL to use GitHub<\/h2>\n<p>There are two pieces we need to configure with GraphiQL to use the GitHub API:<\/p>\n<ol>\n<li>Add our previously generated personal access token to request headers.<\/li>\n<li>Provide the URL to the GitHub GraphQL API endpoint.<\/li>\n<\/ol>\n<p>Let\u2019s start with the request headers. Click the <em>Edit HTTP Headers<\/em> link in the upper right.<\/p>\n<p><a href=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/edit-headers.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-16525\" src=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/edit-headers.png\" alt=\"\" width=\"820\" height=\"444\" srcset=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/edit-headers.png 820w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/edit-headers-300x162.png 300w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/edit-headers-768x416.png 768w\" sizes=\"(max-width: 820px) 100vw, 820px\" \/><\/a><\/p>\n<p>Add a header with key <code>Authorization<\/code> and a value with <code>Bearer #{TOKEN}<\/code>, where token is the personal access token you generated earlier.<\/p>\n<p><a href=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/headers.png\"><img decoding=\"async\" class=\"aligncenter wp-image-16526\" src=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/headers.png\" width=\"860\" height=\"309\" srcset=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/headers.png 1944w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/headers-300x108.png 300w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/headers-768x276.png 768w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/headers-1024x368.png 1024w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<p>It\u2019s not intuitive, but click outside the <em>Edit HTTP Headers<\/em> panel to close the panel and return to the editor.<\/p>\n<p>Finally, enter <code>https:\/\/api.github.com\/graphql<\/code> as the GraphQL endpoint:<\/p>\n<p><a href=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/endpoint.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-16527\" src=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/endpoint.png\" alt=\"\" width=\"682\" height=\"175\" srcset=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/endpoint.png 682w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/endpoint-300x77.png 300w\" sizes=\"(max-width: 682px) 100vw, 682px\" \/><\/a><\/p>\n<h2>Test your configuration<\/h2>\n<p>Let\u2019s ensure we\u2019re ready to go. Copy and paste the following query:<\/p>\n<pre class=\"brush:php\">query {\r\n  organization(login: \"nasa\") {\r\n    name\r\n    url\r\n  }\r\n}<\/pre>\n<p>You should see high-level information on NASA\u2019s GitHub organization:<\/p>\n<p><a href=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/NASA.png\"><img decoding=\"async\" class=\"aligncenter wp-image-16528\" src=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/NASA.png\" width=\"860\" height=\"294\" srcset=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/NASA.png 2040w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/NASA-300x103.png 300w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/NASA-768x263.png 768w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/NASA-1024x350.png 1024w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<h3>Data hierarchy<\/h3>\n<p>Back to our problem: showing the most active pull request comment authors. To get down to this data, we\u2019ll need to access data through several nested relationships:<\/p>\n<p><code>organization =&gt; repository =&gt; pull requests =&gt; =&gt; comments<\/code><\/p>\n<p>We\u2019ll step through this one-by-one below. Don\u2019t worry: It\u2019s not as complex as it might look above.<\/p>\n<h2>Fetch a GitHub organization<\/h2>\n<p>I\u2019m going to fetch data from the <a href=\"https:\/\/github.com\/rails\/rails\">Ruby on Rails repository<\/a> on GitHub. To start, we\u2019ll need to access the <code>rails<\/code> organization:<\/p>\n<pre class=\"brush:php\">query {\r\n  organization(login: \"rails\") {\r\n    name\r\n    url\r\n  }\r\n}<\/pre>\n<p>Pasting the query above should generate output like this:<\/p>\n<pre class=\"brush:php\">{\r\n  \"data\": {\r\n    \"organization\": {\r\n      \"name\": \"Ruby on Rails\",\r\n      \"url\": \"https:\/\/github.com\/rails\"\r\n    }<\/pre>\n<p>In the example above, <code>organization<\/code> is an object. The organization\u2019s <code>name<\/code> and <code>url<\/code> are <a href=\"http:\/\/graphql.org\/learn\/queries\/#fields\">fields<\/a>. Notice we only get the fields we\u2019ve asked for. By comparison, if we used the GitHub REST API, <a href=\"https:\/\/developer.github.com\/v3\/orgs\/#response-3\">more than 30 fields<\/a> would be returned with information on the organization.<\/p>\n<p>The organization <code>login<\/code> is an <a href=\"http:\/\/graphql.org\/learn\/queries\/#fields\">argument<\/a>. These are the REST equivalent of query parameters, but more magical. Any object or field can have its own set of arguments: This is one of the ways GraphQL can eliminate multiple HTTP calls versus REST when fetching data. I\u2019ll demonstrate this shortly.<\/p>\n<p>Notice that as you type in GraphiQL, suggestions are provided. This is the introspective nature of GraphQL:<\/p>\n<p><a href=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/autocomplete.gif\"><img decoding=\"async\" class=\"aligncenter wp-image-16529\" src=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/autocomplete.gif\" width=\"860\" height=\"527\" \/><\/a><\/p>\n<h2>Fetch the <code>rails<\/code> repository<\/h2>\n<p>We\u2019ll find the <code>rails<\/code> repository in a similar nature as the Rails organization. Since a repository belongs to an organization, it is nested under an organization in a GraphQL query:<\/p>\n<pre class=\"brush:php\">query {\r\n  organization(login: \"rails\") {\r\n    name\r\n    url\r\n    repository(name: \"rails\") {\r\n      name\r\n    }\r\n  }\r\n}<\/pre>\n<p>The output should look like:<\/p>\n<pre class=\"brush:php\">{\r\n  \"data\": {\r\n    \"organization\": {\r\n      \"name\": \"Ruby on Rails\",\r\n      \"url\": \"https:\/\/github.com\/rails\",\r\n      \"repository\": {\r\n        \"name\": \"rails\"\r\n      }\r\n    }\r\n  }\r\n}<\/pre>\n<p>We can see the start of the GraphQL magic forming: We\u2019ve now queried across two associated objects (organizations and repositories). We also have a much leaner payload: Fetching a repository with the GitHub REST API may return a response with nearly <a href=\"https:\/\/developer.github.com\/v3\/repos\/#response-3\">300 lines<\/a>.<\/p>\n<h3>Fetch pull requests<\/h3>\n<p>Pull requests belong to repositories, so these are nested under a repository in the query. We\u2019ll fetch the last ten pull requests. Nest the following under <code>repository<\/code> and execute the query:<\/p>\n<p><code>pullRequests(last: 10)<\/code><\/p>\n<p>Notice how GraphiQL automatically added the leaf fields under <code>pullRequests<\/code> after the query was executed:<\/p>\n<p><a href=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/leafs.gif\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-16530\" src=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/leafs.gif\" alt=\"\" width=\"506\" height=\"334\" \/><\/a><\/p>\n<p>This makes exploring a GraphQL API very organic.<\/p>\n<p>Let\u2019s fetch the title of each PR and remove the PR id field:<\/p>\n<pre class=\"brush:php\">pullRequests(last: 10) {\r\n  edges {\r\n    node {\r\n      title\r\n    }\r\n  }\r\n}<\/pre>\n<p>Now, let\u2019s just grab open PRs. Go back to <code>pullRequests(last: 10)<\/code> in GraphiQL and let\u2019s add a new argument.<\/p>\n<p>Start typing <code>states<\/code>. GraphiQL shows <code>states<\/code> as a valid argument, but I\u2019m unfamiliar with the <code>PullRequestState<\/code> type. Just click it, and the docs will appear in the sidebar.<\/p>\n<p><a href=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/states.png\"><img decoding=\"async\" class=\"aligncenter wp-image-16531\" src=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/states.png\" width=\"860\" height=\"382\" srcset=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/states.png 2050w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/states-300x133.png 300w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/states-768x341.png 768w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/states-1024x455.png 1024w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<p>Again, the introspective nature of GraphQL is super helpful. We\u2019re able to focus on building our query and accessing docs as we need them.<\/p>\n<p>So, let\u2019s just specify <code>OPEN<\/code> pull requests:<\/p>\n<p><code>pullRequests(last: 10, states: [OPEN])<\/code><\/p>\n<p><a href=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/open-prs.png\"><img decoding=\"async\" class=\"aligncenter wp-image-16532\" src=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/open-prs.png\" width=\"860\" height=\"321\" srcset=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/open-prs.png 1140w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/open-prs-300x112.png 300w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/open-prs-768x287.png 768w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/open-prs-1024x383.png 1024w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<h3>Comments<\/h3>\n<p>We\u2019re mixing and repeating at this point: The format is similar to what we\u2019ve already done. We\u2019ll grab pull request comments. This completes our first working GraphQL query!<\/p>\n<pre class=\"brush:php\">{\r\n  organization(login: \"rails\") {\r\n    name\r\n    url\r\n    repository(name: \"rails\") {\r\n      name\r\n      pullRequests(last: 10, states: [OPEN]) {\r\n        edges {\r\n          node {\r\n            title\r\n            comments(last: 10) {\r\n              edges {\r\n                node {\r\n                  author {\r\n                    name\r\n                  }\r\n                }\r\n              }\r\n            }\r\n          }\r\n        }\r\n      }\r\n    }\r\n  }\r\n}<\/pre>\n<h2>How Would We Gather the Same Data via GitHub\u2019s REST API?<\/h2>\n<p>If I\u2019m using the existing GitHub API, I\u2019d need to assemble a number of requests to gather this data: fetching an org, fetching a repo, fetching open pull requests, and fetching comments for each pull request.<\/p>\n<p>This is pretty inefficient. Not only does this require many HTTP calls, but each response sends a significant amount of information that we aren\u2019t using. Additionally, I\u2019d have no choice but to navigate the REST API docs to determine endpoints and possible query params. With GraphiQL, you may never have to leave the app to generate the query.<\/p>\n<h3>Queries are like view templates<\/h3>\n<p>If you inspect our working query above, you\u2019ll notice there are several places where I\u2019ve hard-coded argument values: the organization login, the repository name, the number of pull requests to fetch, etc. This doesn\u2019t make the query easily reusable if we\u2019d like to fetch the same information from other repositories.<\/p>\n<p>GraphQL has a number of ways to address this. In general, you should think of GraphQL queries just like you think of view templates.<\/p>\n<h3>Variables<\/h3>\n<p>GraphQL has first-class support for variables, so we can remove these hard-coded values (organization login, repository name, etc.) from the query.<\/p>\n<p>There are three steps to use variables in GraphQL queries. I can\u2019t say it any better than the <a href=\"http:\/\/graphql.org\/learn\/queries\/#variables\">GraphQL docs<\/a>, so I\u2019ve placed the steps below:<\/p>\n<ol>\n<li>Replace the static value in the query with <code>$variableName<\/code>.<\/li>\n<li>Declare <code>$variableName<\/code> as one of the variables accepted by the query.<\/li>\n<li>Pass <code>variableName: value<\/code> in the separate, transport-specific (usually JSON) variables dictionary.<\/li>\n<\/ol>\n<p>Here\u2019s how the GitHub query looks now in GraphiQL:<\/p>\n<p><a href=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/Variables.png\"><img decoding=\"async\" class=\"aligncenter wp-image-16533\" src=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/Variables.png\" width=\"860\" height=\"755\" srcset=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/Variables.png 882w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/Variables-300x263.png 300w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/Variables-768x674.png 768w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<p>Rather than copying my screenshot, I\u2019d suggest modifying the query yourself. If you make any errors, watch GraphQL present debug messages, helping you work through the query construction.<\/p>\n<h3>Fragments<\/h3>\n<p>Let\u2019s say I\u2019d like to fetch each pull request author as well. We\u2019re already fetching user fields for each comment. Do I just copy and paste those fields?<\/p>\n<pre class=\"brush:php\">author {\r\n  name &lt;-- User field\r\n}<\/pre>\n<p>If you\u2019re like me, that feels non-DRY. We should ensure we grab the same data every time we fetch <code>User<\/code> fields. For example, if we decide to fetch an <code>avatarUrl<\/code>, we\u2019d likely want to do that for every <code>User<\/code>.<\/p>\n<p>GraphQL provides fragments for easy reuse. We can define a fragment for user fields:<\/p>\n<pre class=\"brush:php\">fragment userFields on User{\r\n  name\r\n  avatarURL\r\n}<\/pre>\n<p>\u2026and include the fragment in our query.<\/p>\n<p><a href=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/fragment.png\"><img decoding=\"async\" class=\"aligncenter wp-image-16534\" src=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/fragment.png\" width=\"860\" height=\"763\" srcset=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/fragment.png 867w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/fragment-300x266.png 300w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/03\/fragment-768x681.png 768w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<h2>Executing a GraphQL Query via Ruby<\/h2>\n<p>So far, I\u2019ve just used GraphiQL to query the GitHub API. For real-world usage, I\u2019ll need to use a client library.<\/p>\n<p>I\u2019ll use the Ruby <a href=\"https:\/\/github.com\/github\/graphql-client\">graphql-client gem<\/a> to execute the query and the <a href=\"https:\/\/github.com\/tj\/terminal-table\">terminal-table gem<\/a> to display the leader board. I\u2019ve created a <a href=\"https:\/\/github.com\/itsderek23\/github_graphql\">GitHub repository<\/a> with the needed bits to execute the query.<\/p>\n<pre class=\"brush:php\">git clone git@github.com:itsderek23\/github_graphql.git\r\ncd github_graphql\r\ngem install terminal-table graphql-client \r\nGITHUB_TOKEN=&lt;your token&gt; ruby github_graphql.rb<\/pre>\n<p>With this data, we can now build our pull request commenter leader board (full code):<\/p>\n<p><code>+--------------------------+----------+<br \/>\n| Author | Comments |<br \/>\n+--------------------------+----------+<br \/>\n| Rafael Fran\u00e7a | 23 |<br \/>\n| Matthew Draper | 21 |<br \/>\n| Jon Moss | 18 |<br \/>\n| Kasper Timm Hansen | 14 |<br \/>\n| Andrew White | 12 |<br \/>\n| Sean Griffin | 10 |<br \/>\n| Ryuta Kamizono | 10 |<br \/>\n| Arthur Nogueira Neves | 7 |<br \/>\n| Vladimir Dementyev | 7 |<br \/>\n| Klas Eskilson | 6 |<br \/>\n| Robin Dupret | 6 |<br \/>\n| Bradley Priest | 6 |<br \/>\n| kenta-s | 5 |<br \/>\n| Kir Shatrov | 5 |<br \/>\n| Nikolay Shebanov | 5 |<br \/>\n| Koen Punt | 4 |<br \/>\n| Egor Homakov | 4 |<br \/>\n| David Faulkenberry | 4 |<br \/>\n| Jeremy Daer | 4 |<br \/>\n| Eileen M. Uchitelle | 4 |<br \/>\n| Richard Beddington | 4 |<br \/>\n| David Heinemeier Hansson | 4 |<br \/>\n| Travis Hunter | 3 |<br \/>\n| Nathan | 3 |<br \/>\n| Guillermo Iguaran | 3 |<br \/>\n| Mike Busch | 3 |<br \/>\n| Alexander Marrs | 3 |<br \/>\n| Mehmet Emin \u0130NA\u00c7 | 3 |<br \/>\n+--------------------------+----------+<\/code><\/p>\n<p>At this point, we\u2019ve covered enough of the basics for you to explore building your first GraphQL query. There\u2019s certainly more to queries than what we\u2019ve covered (directives, aliases, and more). See the official <a href=\"http:\/\/graphql.org\/\">GraphQL website<\/a> to learn more.<\/p>\n<div class=\"attribution\">\n<table>\n<tbody>\n<tr>\n<td><span class=\"reference\">Reference: <\/span><\/td>\n<td><a href=\"https:\/\/blog.codeship.com\/an-introduction-to-graphql-via-the-github-api\/\">An Introduction to GraphQL via the GitHub API<\/a> from our <a href=\"http:\/\/www.webcodegeeks.com\/join-us\/wcg\/\">WCG partner<\/a> Derek Haynes at the <a href=\"http:\/\/blog.codeship.com\/\">Codeship Blog<\/a> blog.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>RESTful, JSON-delivering APIs are today\u2019s default choice when building an API. However, there\u2019s a new API kid on the block that\u2019s generating considerable attention: GraphQL. GraphQL is an entirely new way to consume and build APIs. Done right, you can build wonderfully tight integrations that aren\u2019t possible with REST APIs. Today, we\u2019ll get firsthand exposure &hellip;<\/p>\n","protected":false},"author":225,"featured_media":927,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[452,451,450],"class_list":["post-16521","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-web-development","tag-git","tag-github","tag-graphql"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>An Introduction to GraphQL via the GitHub API - Web Code Geeks - 2026<\/title>\n<meta name=\"description\" content=\"RESTful, JSON-delivering APIs are today\u2019s default choice when building an API. However, there\u2019s a new API kid on the block that\u2019s generating considerable\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"An Introduction to GraphQL via the GitHub API - Web Code Geeks - 2026\" \/>\n<meta property=\"og:description\" content=\"RESTful, JSON-delivering APIs are today\u2019s default choice when building an API. However, there\u2019s a new API kid on the block that\u2019s generating considerable\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/\" \/>\n<meta property=\"og:site_name\" content=\"Web Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/webcodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2017-03-10T10:15:49+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Derek Haynes\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Derek Haynes\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/\"},\"author\":{\"name\":\"Derek Haynes\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/2aaa4e7b1909ee5cb0232799fd8ed087\"},\"headline\":\"An Introduction to GraphQL via the GitHub API\",\"datePublished\":\"2017-03-10T10:15:49+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/\"},\"wordCount\":1850,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\",\"keywords\":[\"Git\",\"GitHub\",\"GraphQL\"],\"articleSection\":[\"Web Dev\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/\",\"name\":\"An Introduction to GraphQL via the GitHub API - Web Code Geeks - 2026\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\",\"datePublished\":\"2017-03-10T10:15:49+00:00\",\"description\":\"RESTful, JSON-delivering APIs are today\u2019s default choice when building an API. However, there\u2019s a new API kid on the block that\u2019s generating considerable\",\"breadcrumb\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/#primaryimage\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.webcodegeeks.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Web Dev\",\"item\":\"https:\/\/www.webcodegeeks.com\/category\/web-development\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"An Introduction to GraphQL via the GitHub API\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"name\":\"Web Code Geeks\",\"description\":\"Web Developers Resource Center\",\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.webcodegeeks.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/webcodegeeks\",\"https:\/\/x.com\/webcodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/2aaa4e7b1909ee5cb0232799fd8ed087\",\"name\":\"Derek Haynes\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/a7ce64212b9d27231a5b04b67bcca0ca6d74aae85f29701036baba1fccc3d053?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/a7ce64212b9d27231a5b04b67bcca0ca6d74aae85f29701036baba1fccc3d053?s=96&d=mm&r=g\",\"caption\":\"Derek Haynes\"},\"description\":\"Derek Haynes is a cofounder of Scout, an avid Rubyist, a bungling Elixirist, and a lover of beautifully presented data.\",\"url\":\"https:\/\/www.webcodegeeks.com\/author\/derek-haynes\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"An Introduction to GraphQL via the GitHub API - Web Code Geeks - 2026","description":"RESTful, JSON-delivering APIs are today\u2019s default choice when building an API. However, there\u2019s a new API kid on the block that\u2019s generating considerable","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/","og_locale":"en_US","og_type":"article","og_title":"An Introduction to GraphQL via the GitHub API - Web Code Geeks - 2026","og_description":"RESTful, JSON-delivering APIs are today\u2019s default choice when building an API. However, there\u2019s a new API kid on the block that\u2019s generating considerable","og_url":"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/","og_site_name":"Web Code Geeks","article_publisher":"https:\/\/www.facebook.com\/webcodegeeks","article_published_time":"2017-03-10T10:15:49+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","type":"image\/jpeg"}],"author":"Derek Haynes","twitter_card":"summary_large_image","twitter_creator":"@webcodegeeks","twitter_site":"@webcodegeeks","twitter_misc":{"Written by":"Derek Haynes","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/#article","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/"},"author":{"name":"Derek Haynes","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/2aaa4e7b1909ee5cb0232799fd8ed087"},"headline":"An Introduction to GraphQL via the GitHub API","datePublished":"2017-03-10T10:15:49+00:00","mainEntityOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/"},"wordCount":1850,"commentCount":0,"publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","keywords":["Git","GitHub","GraphQL"],"articleSection":["Web Dev"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/","url":"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/","name":"An Introduction to GraphQL via the GitHub API - Web Code Geeks - 2026","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/#primaryimage"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","datePublished":"2017-03-10T10:15:49+00:00","description":"RESTful, JSON-delivering APIs are today\u2019s default choice when building an API. However, there\u2019s a new API kid on the block that\u2019s generating considerable","breadcrumb":{"@id":"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/#primaryimage","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/web-dev-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.webcodegeeks.com\/web-development\/introduction-graphql-via-github-api\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.webcodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Web Dev","item":"https:\/\/www.webcodegeeks.com\/category\/web-development\/"},{"@type":"ListItem","position":3,"name":"An Introduction to GraphQL via the GitHub API"}]},{"@type":"WebSite","@id":"https:\/\/www.webcodegeeks.com\/#website","url":"https:\/\/www.webcodegeeks.com\/","name":"Web Code Geeks","description":"Web Developers Resource Center","publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.webcodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.webcodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.webcodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/webcodegeeks","https:\/\/x.com\/webcodegeeks"]},{"@type":"Person","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/2aaa4e7b1909ee5cb0232799fd8ed087","name":"Derek Haynes","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/a7ce64212b9d27231a5b04b67bcca0ca6d74aae85f29701036baba1fccc3d053?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a7ce64212b9d27231a5b04b67bcca0ca6d74aae85f29701036baba1fccc3d053?s=96&d=mm&r=g","caption":"Derek Haynes"},"description":"Derek Haynes is a cofounder of Scout, an avid Rubyist, a bungling Elixirist, and a lover of beautifully presented data.","url":"https:\/\/www.webcodegeeks.com\/author\/derek-haynes\/"}]}},"_links":{"self":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/16521","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/users\/225"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/comments?post=16521"}],"version-history":[{"count":0,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/16521\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media\/927"}],"wp:attachment":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media?parent=16521"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/categories?post=16521"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/tags?post=16521"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}