GraphQL Is the King. Long Live the King (R.I.P. REST)
GraphQL is the King. Long Live the King! (R.I.P. REST)
It started a few months back. I was hearing whispers of this new tech called GraphQL. That name was weird, but people talked about this auto-completing IDE that somehow related to it.Then I learned more. GraphQL was another in a line of technologies that were emerging from the hipster catacombs at Facebook. Well then, I thought to myself, I may not like their product (like at all), but if this new tech came from the same people who brought me React, there’s got to be some promise in it.The opportunity came shortly after to drive down to the Facebook office for a meet up. They did the GraphQL spiel with lots of self deprecating jokes on the name, showed us the StarWars GraphiQL demo, and that was that. Really, that was all it took. I was hooked.While GraphQL has been permeating the Facebook architecture since 2012, it was only recently announced as ‘a thing’ to the public this year (2015). It seems like it’s quickly gained momentum, with a slew of developers, including myself, championing it.I spun up a test GraphQL POC layer over an already existing REST server, and in a matter of days had a fully featured GraphQL API. Sure, it wasn’t the optimal setup for a GraphQL schema, but it was enough.What follows is a fleshed out version of an hour long presentation I gave on GraphQL. This will be a two part series, with Part 1 (this part) focusing on the many reasons why GraphQL is going to blow REST out of the water, and hopefully convince you to start playing around with GraphQL today.In Part 2, I’ll walk you through setting up your own GraphQL schema using Node. By the time you’re done, you’ll likely be sharing the wonders of GraphQL through your team, and be treated like a god once they’ve adopted the technology.Why is GraphQL the Greatest Thing Since Sliced Bread?Let’s start at the beginning…What is GraphQL?GraphQL is a query language. It requests data which is then returned in the same shape it was requested in. It looks a lot like a JavaScript object, and produces constantly predictable results. In practice, it looks a little something like this:{  cars(make: “Tesla”) {    model  }}Above we are requesting a list of cars that are filtered by the make, and we are asking for only the model to be returned. (More on how the data is returned below)Wait… What?GraphQL Returns Only the Data You RequestYou’ve probably worked with REST before in some way. Likely it wasn’t what REST fanboys refer to as true REST. It was probably something that started out with the best intentions to be REST, and then, slowly over time morphed into a RESTish amalgamation.In any case, you’ve probably called a REST route that returns way more information than you need. So what do you do in that case? There’s really only a few options. You can:filter the data on the front endadd a url parameter to filter the data on the back endcreate a new route that returns only the data you needNone of those scenarios are ideal, but in most cases you’ll probably go with the first and lament the many weaknesses of a REST service. (Maybe lament is a strong word).Someone’s gonna rail on me for my REST remarks in the comments, I can feel it. Meh. Rock the boat!With a GraphQL schema in place, this becomes a nonissue. A GraphQL API can function perfectly well with a single endpoint, and it only returns the data you request. Smaller payloads equals bigger win.GraphQL Returns Data in the Same Shape You Requested ItYou remember our query up top? Here it is again just so you don’t need to scroll.{  cars(make: “Tesla”) {    model  }}A query like this returns data in the same shape we requested it in. In this case, our API will send us something like this:{  “data”: {    “cars”: [      “model”: “Model S”,      “model”: “Model X”    ]  }}Here’s a more complicated example from the StarWars GraphiQL technical demo that Facebook setup.query NestedQuery {  hero {    name    friends {      name      appearsIn      friends {        name      }    }  }}This example yields the following result:{  "hero": {    "name": "R2-D2",    "friends": [      {        "name": "Luke Skywalker",        "appearsIn": [ "NEWHOPE", "EMPIRE", "JEDI" ],        "friends": [          { "name": "Han Solo" },          { "name": "Leia Organa" },          { "name": "C-3PO" },          { "name": "R2-D2" }        ]      },      {        "name": "Han Solo",        "appearsIn": [ "NEWHOPE", "EMPIRE", "JEDI" ],        "friends": [          { "name": "Luke Skywalker" },          { "name": "Leia Organa" },          { "name": "R2-D2" }        ]      },      {        "name": "Leia Organa",        "appearsIn": [ "NEWHOPE", "EMPIRE", "JEDI" ],        "friends": [          { "name": "Luke Skywalker" },          { "name": "Han Solo" },          { "name": "C-3PO" },          { "name": "R2-D2" }        ]      }    ]  }}Notice how each instance of a “hero” is shaped exactly like the query. Too cool.Oh yeah, Doctor? I use GraphQL now, so, yeah… GraphQL is cool. Won that exchange.I see what you’re thinking. “Data returned in the same shape I requested it in is all well and good,” you’re thinking, “but it’s not enough to convince me to write a brand new schema.” You’re a tough cookie.Hmm. Have you seen the IDE? I’m going to show you the IDE.GraphQL is Self Documenting, and Enables Auto-Complete in the IDEHere’s a peek at the IDE running over a schema I set up. As soon as I start typing, all available fields are listed. No more checking the JSON to make sure the key’s I’m parsing are correct, just type three letters, enter. Done.If you’re a front-end dev and aren’t salivating right now, something is wrong with you.But if a kickass IDE still isn’t enough for you, then it’s time to pull out the big guns. Let’s bring performance into the mix (not to mention the increased performance of your front end dev’s when working with the syntax and IDE above.)GraphQL Sends a Single Request to the API and Returns a Single ResponseNeed I say more? Ok, I probably do if I want to effectively get my point across.Let’s say you have a page that requires some user data to determine a list of posts that are associated with that user. On top of that, you need to also fetch some data to determine which UI components that user will see in the nav bar (maybe Admins see one menu, Users see another).I don’t think that this is at all an unheard of situation. If you’re backed by a REST API, you may query the API once for the user data. Then you query the API two more times, once to fetch the list of posts, and one more time to get the UI components.The user is sitting in a busy coffee shop with shitty wifi, or is working on a phone, or maybe lives in an area with a bad connection. Each request take’s this user one second. So in this case it takes the user 3 seconds to display everything on his page. That’s way too long.I don’t know about you, but I’ve seen pages with more queries than this, and if the users reception is poor it can take a significant amount of time to see anything tangible.Now you might be thinking that you could avert this problem with a new route that sends all the data for this view. Fair enough. But, let’s say that at some point the needs of this page change, necessitating new data.But another view uses this route, maybe on the mobile version, or just another page. You can carefully update the route to provide the new data, or add a url parameter to allow this route to support other views, or create another new route to support this view.All of this must be carefully executed to support other pages, or older versions. Not to mention the work associated with creating any one of these options. So much maintenance!With GraphQL, there is no need for any of that. We simply change the data we request, and the GraphQL endpoint will handle it. Easy.No seriously. It’s that easy.Quick recap: With GraphQL you can structure your request however you need, including all the data points you require, send it all to a single endpoint (even if you’re calling a third party API) and the server will process all the necessary logic.By simply cutting the client to service interaction to a single call, you’d see a 3x performance boost for the above example user, and when the view updates, you won’t need to worry about maintaining your service code to accommodate it.But wait, there’s more…GraphQL is Strongly TypedEach field in your schema is enforced by a GraphQL type. This is nice for a number of reasons. My favorite: the IDE let’s you know what data is accepted, so any guesswork there might be is gone (really, that keywords field takes a comma separated string, not an array???).Queries are Backed By Arbitrary CodeThe schema is all backed by arbitrary code that you write. This is awesome. Why? First of all, it allowed me to copy my current UI calls right into the GraphQL schema, which got it up and working in a matter of hours. Obviously this isn’t an ideal setup, but it’s pretty cool.It also means that you can communicate with any data source you need in order to get the data your schema required. Need to get some data from a third party API, a REST service, and directly from your database? Yeah, that won’t be an issue.And you still only make a single request from the client.ConclusionBasically, GraphQL is the future of the internet. For the next few years anyway. REST was great, served a lot of good purposes, and will likely remain how we structure our services even with a GraphQL layer for our own sanities sake. But, IMHO GraphQL is the future.I’ll be back again with a guide on how to write a GraphQL schema. It’s actually pretty simple once it clicks. In that post we’ll write our schema, back it with arbitrary calls, and get GraphiQL setup. Hopefully I’ll see you then.