This all started from personal wish to try GraphQL, to see how it works, to code something, and then make a decision, based on own experience. I also tend to grasp new technologies, as fast as I can, and that is why this project dedicated to new things, at least some first touch.
GitHub API, REST vs. GraphQL, XmlHttpRequest vs. Fetch API, HTML5
template, ES6 String Literals, ES2017
async/await, URLSearchParams API, Chrome Canary, NodeJS, npm vs. bower, Bootstrap
v4-dev, Pace progress bar, OAuth vs. Auth0, deployment to Heroku.
I was working on set of work-related tasks and personal sandbox projects, and I came up with task idea:
Get list of GitHub repositories based on my custom data about owner and name.
But here, I will share my experience about working directly with GitHub API, with their version 3 (REST-based) and version 4 (GraphQL-based).
So let’s say I have array of objects representing GitHub repository owner and name:
For my test application, I have 20 records. It’s important, because later on I will analyze performance (by number of requests, time and size of data). And I have 3 variants to get those data:
- GitHub API v3 – REST-based API
- GitHub API v3 via github-tools/gitgub – github-api wrapper.
- GitHub API v4 using GraphQL
For educational and testing purpose, I use Fetch API to create request to server.
GitHub API v3 – REST-based API
GitHub API v3 via github-tools/gitgub – github-api wrapper.
After you include
GitHub.bundle.min.js in html code, you will have
window.GitHub available, and u can code. And this GitHub API wrapper, gives me easier way regarding authentication and existed functions to fetch repository data by owner and name with ability to view details. It’s also good, that this wrapper already knows public URL to API, so no need to provide it explicitly.
In both code snippets above, the flow is next:
- I get my custom data and token and later I pass to functions.
- Then I provide repo owner and repo name to either my personal code to fetch/GET or “github API wrapper” code.
- Then, I render every data on page.
And if we compare both approaches, performance of getting data from server is quite the same. Let’s say I want to render 20 records, so I will send 20 GET requests, and as soon as I fetch it, I show on page. And if u look to structure of response objects, it’s huge – GitHub API returns lot of data.
And here is time for GraphQL to step into. Main goal of GraphQL is simplification of complex requests. You can simply program what requests is going to be, and what you want to receive in response.
GitHub API v4 using GraphQL
It’s not simple example I’ve got for myself. Please research Google for simpler examples. But I had a task, and my goal was to implement it. In fact I didn’t come up with below query at first time – I created post on GitHub Platform Forum, and people helped me to realize, how to do it. Here is IDL file content of GraphQL query:
This content can be executed in GraphQL Explorer, which requires GitHub authentication:
Yes, v3 approach creates dozen of requests (due to v3 design, there is no endpoint to fetch list of repositories), and v4, gives closer ability, and does only 1(2) request(s).
Looking to Chrome Canary v63 Networking tab now, to compare time performance:
- v3 approach it sends 40 requests (OPTIONS+GET), which takes 1.4/1.6/1.8 sec
- v4 it sends ONLY one POST request (in fact 1 OPTIONS + 1 POST), which takes ~1.5/1.8/2.0 sec.
Yes, from time perspective, all approaches are quite the same, and even sometimes GraphQL is slower. But interesting observation, that if ONLY one approach works in browser, then I guess requests cashed, and then BOTH approaches take on average ~1.2 sec, which is ok, but complicated to calculate who is better.
Looking to Networking tab, but considering number of server-returned properties:
- v3 approach in scope of one GET request about repository info gives you 108 unique properties/data fields (which is 20*108 = 2160 properties per one total request), and
- v4 approach (GraphQL) gives you ability to adjust wanted list of properties from server. In my example one POST request offers in response 21 unique properties, which is multiplied by requested 20 repositories, and in total it’s 20*21 = 420 properties. And this is great, this is why GraphQL does win…
Looking to Networking tab, but to total size of requests.
- v3 approach goes via 40 requests (for 20 repos) and it downloads 93 kB.
- v4 approach goes via 2 requests (for 20 repos) and it downloads 6.1 kB.
Other Tech Notes
First of all – we can use
import/export, with no transpilers now. Hooray, finally… It was available since early Chrome Canary versions, then Chrome v60 (w/ flag), and since Chrome official v61 we can run our pages freely. And since NodeJS v 8.5.0 ES Modules are available also, under files with extension
Twitter Bootstrap v4
I chose Twitter Bootstrap for my trivial UI, not because I know it, or all web community uses it, but to test their recent code changes in
v4.0.0-beta, which I discovered is buggy. I follow their GitHub repo, and I was able to
bower install bootstrap#v4-dev directly from dedicated master with fixes to use it locally. But then, Sep-05-2017, they dropped bower support, and next day, when I deleted
bower_components, I wasn’t able to install at all. So I did
npm install bootstrap#v4-dev, and latest code is able for me to use. They also preparing to having dedicated bootstrap-js and bootstrap-css. Details here.
Fetch API vs. XMLHttpRequest
During work on the task, I experienced an issue, that using Fetch API, browser sends 2 requests to GitHub server: OPTIONS + GET. I’ve read some helpful info here, and later on just tried simple XmlHttpRequest, and request was only one – GET. If I provide any kind of headers to Fetch options, it then goes OPTIONS => GET. If I omit options.headers, then Content-Type is text/plain by default, it it goes only GET request. With GitHub API v4 requests, it goes OPTIONS+POST.
My point is, that they are different, their definition might be similar, but behavior, in some edge cases really differs. In my case, it’s somehow related with CORS and requests from my host (localhost, github-pages or Heroku instance) to public server.
BTW, if I look on Safari to Network tan, v4 approach (GraphQL) downloads 12kB and it takes 0.35-1.50 sec, and Fetch API does it via ONLY ONE POST request.
- github-tools/github – GitHub API v3 wrapper, which I used in my example.
- mikedeboer/node-github – recently spotted, but not used in my example.
- mulesoft/js-client-oauth2 – Generic library for OAuth client connections, which I used in my example.
- cfsghost/passport-github – another wrapper, forked version of v3 based wrapper “pasport-github” with OAuth support, based on PassportJS.
Auth0 vs OAuth
I understood, that OAuth looks specific, but at the first glance, it’s very complicated to grasp, how it is different from Auth0, OpenID, SSO, Okta and other similar authentication services. I’ve read documentation from GitHub and other pages, for 2 days, and I did some variant, but I feel, like there is better way, smarter. But assuming it’s first time I worked with OAuth and GitHub API, I think it’s acceptable for me to stop there. I think, when I have one more project rlated with OAuth, I will watch this video one more time.
GitHub Apps vs GitHub OAuth Apps
It’s first time, I touched this area, and as all apps, these both are available for being in marketplace. So if there is need to create application, and earn money on it, there is technical ability, but application should meet requirements first before going to market. I did not have such purpose, but was interesting o wok with the technology.
NodeJS, ExpressJS, Heroku
It’s so easy to setup NodeJS/ExpressJS project/server using Heroku. I used deployment approach from github repository. So if I push my changes, in a few seconds, it’s deployed, and I ca test my almost full functioning web site.
- Async/Await will make your code simpler [11-Aug-2017]
- Using Fetch API [css-tricks.com, May-02-2017]
- GraphQL vs Firebase [medium.com, May-05-2017]
- GIFBOT – BUILDING A GITHUB APP [scottlogic.com, May-22-2017]
- The steady rise of GraphQL [medium.com, May-23-2017]
- GraphQL, the future of APIs [altplatform.org, Jul-13-2017]
- A Game of Data and GraphQL [medium.com, Aug-03-2017]
- GraphQL schema stitching [medium.com, Sep-07-2017]
- React, Apollo and GraphQL [medium.com, Sep-08-2017]
- I wanted real time GitHub push notifications. So I built a Chrome extension. [medium.com, Sep-06-2017]
- Getting Started on Heroku with Node.js [devcenter.heroku.com]
- What the Heck is OAuth? [stormpath.com, May-11-2015]
- Everything You Wanted to Know About OAuth 2 [auth0.com, Apr-20-2016]
- Auth0 vs. OAuth.io [stackshare.io]
- Node.js Weekly Update — 15 September, 2017 [medium.com]
- Securing Node.js RESTful APIs with JSON Web Tokens [medium.com, Sep-04-2017]
I also published this article to Medium.