A Complete Beginner's Introduction to GraphQL

Sam Sycamore

Off-grid web developer and technical writer

Why we use GraphQL, how it differs from REST, and how TakeShape fits into the GraphQL ecosystem.

Since the dawn of the dot-com revolution, REST APIs have been the primary means by which applications pass data around on the web.

Make no mistake: RESTful conventions still dictate how the majority of APIs operate today.

But over the last few years, GraphQL has emerged as a viable - and indeed, sometimes preferable - alternative.

By the end of this article, you should have a better understanding of:

  • What is GraphQL?
  • Why was GraphQL created?
  • How does GraphQL compare with REST APIs?
  • How does TakeShape fit into the larger GraphQL ecosystem?


What is GraphQL?

In truth, GraphQL is more than a mere alternative to REST APIs. It represents a fundamentally different approach to working with API data. That's because GraphQL is not a set of "best practices" like REST, but a full-fledged query language for APIs - as well as a runtime for fulfulling those queries, as we will see.

Because of its flexibility, GraphQL can be integrated at any and all levels of a web app's tech stack. It can even be stacked on top of an existing REST API (or multiple APIs, as it turns out) in order to streamline and simplify the flow of data. This is why GraphQL is sometimes referred to as the "middle-end" bridging the gap between front- and back-end development.


What Problems Does GraphQL Solve?

In order to understand what makes GraphQL such a useful tool, it helps to know about the context in which it was created.

GraphQL was originally formulated by Facebook in 2012. At that moment in time, the engineers needed to solve a few interconnected problems:

  1. How can we handle the highly relational data of a social media site more efficiently?
  2. How do we avoid sending too much data across limited mobile networks to smartphone apps?
  3. How can we make our server-side data easier for client-side developers to work with?

GraphQL largely solves those first two problems by allowing you to declaratively fetch only the specific data you need from an API. Its simplicity makes it a breeze for front-end devs to pick up.

When you work with a conventional API, you make a call to a URL and have to deal with whatever pile of data the server sends back to you.

And if you need to grab more data from that API, you might have to take several trips to get there. That's a lot of data being moved around unnecessarily.

With GraphQL, you ask the API to send over only the pieces of data that you specifically need.

And because it all flows through a single endpoint, you only need to visit the API one time to grab everything you need.

This makes it much more efficient than RESTful APIs in some cases.

That said: these are two very different things that fulfill different needs.


GraphQL vs. REST APIs - What's the Difference?

To get a better sense of how these tools compare and contrast, let's consider the data behind a typical blog with multiple contributors. Each of these authors has a profile, a collection of posts, and a list of followers.

If this data were delivered according to RESTful conventions, you would need to talk to three endpoints:

  • user/[uid] returns the profile of an author with a given user ID
  • user/[uid]/posts returns the author's posts
  • user/[uid]/followers returns their follower list

Querying these endpoints might return some data that looks like this:

{
   "user": {
       "uid": "35073",
	   "role": "contributor",
       "firstName": "Kelly",
	   "lastName": "Clark",
       "email": "kellyclark@fakemail.com",
	   "postCount": "2",
	   "followerCount": "2",
	   "signedUp": "March 1, 2019",
	   "lastSeen": "April 25, 2021",
   }
}

{
   "posts": [{
       "id": "95843",
       "title": "Introduction to Topic",
       "subtitle": "Getting to Know a New Thing",
	   "body": "Webster's dictionary defines definitions as ..."
	   "likes": 64,
   },
   {
       "id": "95844",
       "title": "Introduction to Topic Pt.2",
       "subtitle": "Getting to Know More",
	   "body": "Webster's dictionary still defines definitions as ..."
	   "likes": 12,
   }]
}

{
   "followers": [{
       "uid": "47582",
	   "role": "admin",
       "firstName": "Tom",
	   "lastName": "Thumb",
       "email": "tomthumb@fakemail.com",
	   "postCount": "99",
	   "followerCount": "99",
	   "signedUp": "April 1, 2010",
	   "lastSeen": "May 5, 2021",
   },
   {
       "uid": "83756",
	   "role": "editor",
       "firstName": "Terry",
	   "lastName": "Smith",
       "email": "terrysmith@fakemail.com",
	   "postCount": "800",
	   "followerCount": "20",
	   "signedUp": "June 10, 2015",
	   "lastSeen": "May 3, 2021",
   }]
}

Some of the more obvious problems arise when you need to access nested data inside of those endpoints.

For instance, what if you want to return the names of all of our user's followers who liked a specific post?

You would have to interact with all three of the endpoints mentioned above, and bring back that entire pile of data wholesale - you now have to wade through all of the author's information, all of their blog posts and the associated data, and all of their followers (and all of the info about all of them).

Just to return the author of a post, the title of that post, and the names of a few followers.

That's a whole lot of extra data coming along for the ride.

And that's just a single user - what if we wanted to display the same data but for a list of users? How about the followers of the followers?

The sheer volume of data that would have to be passed around is exponentially greater than what's actually needed. It quickly becomes a real pain to try to parse the responses.

There is a potential workaround here: you could simply create a custom, specialized endpoint to handle this specific query. But then, are you going to make a specialized endpoint to serve every unique query you might need?

That's not very RESTful. One of the key reasons for REST is to standardize how we handle data to make all of our lives easier. From the developer's perspective, it's not going to be clear or obvious how to work with an API that features highly custom endpoints for specific use cases.

The core problem here is that this data is relational - the endpoints interact with one another. There is no single ideal path to query for the aforementioned data according to RESTful conventions.

By contrast, if you were to implement GraphQL in the stack, you could write a query that points directly at the specific pieces of data you need, and then the GraphQL runtime does the rest of the work.

Our earlier example of fetching the names of all followers who Like a particular user's post would lead to a GraphQL query that looks something like this:

query {
   User(uid: "35073"} {
       name
       posts {
	   id
           title
       }
       followers {
           name
       }
   }
}

And in return, you would receive precisely that information - no more or less. Sure looks a lot cleaner, wouldn't you say?

As you might imagine, this can be orders of magnitude more efficient for both the client and the server, which now have significantly less data to pass around for no good reason.


The GraphQL Ecosystem - It's Big

One thing to note is that GraphQL is a specification, not an implementation. There are many implementations to choose from - in fact, the open-ended nature of GraphQL's spec has led to a rapidly growing ecosystem of tools and services. You can potentially find GraphQL at every level of your tech stack, from front-end user interfaces to back-end database functionality.

The full breadth of the GraphQL ecosystem is beyond the scope of this introductory article. Forget "ecosystem" - it's really becoming more like an entire universe of engineering unto itself.

In any given GraphQL-based app, you may encounter it at the level of client, gateway, server, and/or database.

Here at TakeShape, we leverage the power and flexibility of GraphQL to alleviate many of the common growing pains associated with conventional APIs and Jamstack architecture.

TakeShape can serve as your app's GraphQL gateway, server, and database. It can also be easily integrated with other servers, databases, and clients.

Whether your data originates from a REST or GraphQL API - or indeed, many such points of origin - our API Mesh can consolidate everything you need into a single GraphQL endpoint that couldn't be simpler to communicate with through your app's front end.

It's free to get started, and the generous free tier means you can tinker to your heart's content without fear of unexpected fees. Give TakeShape's API Mesh a try today!