๐ค What is GraphQL?
GraphQL is a query language for Web APIs. GraphQL itself is not a tool or a framework, it is a language
As a developer, here are three things I love about GraphQL
- I can ask for what I need, and I get exactly that
- I can get many resources in a single request
- I can use a type system to see what is possible from one single endpoint
ย
ย
This may not make complete sense yet, so let's take a step back and describe GraphQL to you...
New to Web APIs?
An Application Programming Interface (API) is how programs talk to each other. Much like our facial expressions and language is how we interface and communicate with each other, applications need defined protocols and standards for talking to each other, so they know what to expect and how to understand.
GraphQL is one of the many languages and standards of Web APIs. In my limited experience, REST is the dominating standard for web APIs; however, GraphQL is quickly rising as a language that solves problems REST cannot.
ย
Have you heard of REST?
If you're a programmer, I bet you haven't heard of rest! haha. ha.
If you've heard of GraphQL, you've probably heard of REST. GraphQL solves the problems and inefficiencies many programmers find with REST, a standard for interaction with a Web API. Therefore as a substitute to REST, GraphQL is like REST in that it is not a tool. However, REST is more of a standard, while GraphQL is more than a standard โ it is a language. There are defined expectations for queries, retrieving fields, mutations, and more.
ย
New to building Web APIs?
To further engrain that GraphQL is not a tool, GraphQL isn't a package you install or import. It is a language that dictates how clients talk to your Web API. So how do you implement GraphQL into a Web API? Typically, there are tools that do that for you.
Python
- Library - Graphene
- Django - Graphene-Django
- Flask - Flask-GraphQL
- FastAPI - Graphene
Node.js
- Library - GraphQL.js
- Express - GraphQL-Express
- Apollo (a GraphQL server framework)
ย
โณ A Brief History of GraphQL
2012 - Created at Facebook
2012 - Shipped with Facebook's native iOS app rewrite
2015 - Open Sourced
2020 - 94% of developers who used it want to continue using it
๐คทโโ๏ธ Why GraphQL?
What is the problem that GraphQL solves?
ย
Let's say you're consuming an API for a social media platform. What kind of data resources are you looking for?
- Pictures
- User Info
- Likes
- Posts
If you're familiar with REST, a REST API endpoints for this app may look like this:
- /newsfeed โ> [post IDs]
- /post/{id} โ> picture ID, user ID, likes
- /picture/{id} โ> picture data
- /user/{id}/picture โ> commenter profile pic
ย
๐จ Problems
What's the problem with the REST approach?
๐ Scalability
As you can see, the data examples alone barely scratch the service. And when data resources grow, REST Endpoints must be added. So REST APIs can easily grow at a fast pace and become too much to manage.
๐คฎ Too much data
With REST, the fields I get from each endpoint cannot be changed. If I just want to get the user who posted a post, the
/post/{id}
endpoint returns more than just the user โ it also returns the picture ID
and the number of likes
. I don't need all of that, and such inefficiency can be costly in the long run. ๐ต Complicated
Certain use cases can lead to multiple, complicated requests to get the resources I want. Let's say I want to get the profile picture of every user who posted on the newsfeed.
/newsfeed
I need to get all thepost ID
from the newsfeed
/post/{id}
I then need to get theuser ID
of who made each post
/user/{id}/picture
I then use theuser ID
from each post to get the profile picture
Now that's complicated.
๐ฅณ The Solution: โจGraphQLโจ
Let's go through each problem and see how GraphQL tackles it.
๐ Scalability
On the right is an example of a single request to the GraphQL endpoint for our imaginary social media platform. Posts, comments, and users are all accessible from one request! With Graphql everything is accessible from a single endpoint. Forget about
/newsfeed
, /post
, /users
, etc. โ it's all under /graphql
!ย
๐ Don't get more data than you need
With GraphQL, you get exactly what you need. In each request, you can specify what fields are to be returned. If you want to add another field later on, like a commenter's username, simply add it into the request!
๐ค Simplified usage
So we know that GraphQL puts all resources under one endpoint, but how does it do this and keep things simple? A type system defines the fields available in a type as well as a type's relationship with other types. So if we get an overhead perspective, we can see that this is what puts the graph in GraphQL.
๐ Let's recap why GraphQL is cool
๐ Get many resources in a single request
GraphQL allows clients to get many resources from one endpoint. So instead of multiple requests for a complex query, with GraphQL you can do it all in one request.
- Clients face less complexity and save time by only performing one request.
- Developers of the GraphQL server don't need to implement separate endpoints for every resource. Therefore, it scales well.
ย
๐ Ask for what I need, get exactly that
With REST, you are stuck with the amount of data you get from an endpoint. GraphQL allows clients to specify what fields they need from the endpoint.
- Clients can expect what data they are receiving
- Clients save time loading and parsing data
๐ค Describe what's possible with a type system
This is GraphQL's magic behind putting all resources in one end point. instead of
post
being an endpoint, it is a type. The GraphQL server can be configured to describe relationships between types, allowing for nested types and putting the Graph in GraphQL.- Again, everything is wrapped under one endpoint
- Human clients can typically view documentation generated from the type system
ย
๐ How can I start?
We won't be covering how to create a GraphQL API โ that's a whole other animal โ but with GraphQL growing in popularity, chances are you will have many opportunities to use it!
๐จ Set up
We use
fetch
for this example to make requests to the Web API (you don't have to use fetch
). If you're not using the example repository, install fetch
using this command:npm install node-fetch
Now, let's starting writing code. In our main file (you can call it
app.js
), let's import fetch
and set our URL endpoint. We are using PeterPortal Public API (a student-developed Web API for course discovery at UC Irvine) for this example.// We use fetch for this example. A popular alternative is axios. const fetch = require('node-fetch'); // HTTPS does not work right now! const url = "http://api.peterportal.org/graphql";
๐โโ๏ธ Query
This is the hardest part if you're new to GraphQL. Most GraphQL APIs have a playground for you to test things out โ otherwise, you'll have to rely on the documentation available to you to view available queries, parameters, and types.
In
app.js
we're going to make a query to get the information of the course DANCE3
// The query is written as a string -- We'll JSONify it laterrr const query = ` query { course(id: "DANCE3"){ id department school professor_history { ucinetid phone } } } `;
โ Request options
We're almost there! We need to specify what gets sent to the Web API, and for
fetch
, we do that by defining options
. There are two things about the request options that set GraphQL apart from REST.
- The query string will be inserted into the
body
of the request. If you're familiar with REST, you don't see this every day โ usually, the query is written within the URL.
- This means you'll be sending this request as a POST request, not a GET request. To be clear, with GraphQL, whether you are reading, writing, updating, or deleting, you are making a POST request.
Continuing in
app.js
, let's define our options! If you're following along with PeterPortal Public API, we need to define x-api-key
in our headers
. While not all Web APIs require an API key, most do โ you need to check the Web API's documentation to see how they'd like you to authenticate. In our case, we register for an API key and send it in our request's headers.// The options to be used as arguments when we call fetch const options = { // This contains our query. We send it in the body of the request. body: JSON.stringify({query}), // Because our request contains information in the body, we must send it as a POST request // All clients consuming a GraphQL API must use POST!! method: "POST", // Not necessary for every Web API, but it's good practice (and required for PeterPortal API) headers : { "Content-Type": "application/json", "x-api-key": "get your API key here: http://api.peterportal.org/docs/Getting-Started/Register-Here/" } };
๐จ And fetch!
Now we send our request! I'm not going to get into the specifics on how
fetch
sends requests, but as a basic overview, fetch
is promise-based. This means, we don't get the response โ the data we need โ until the promise is fulfilled. Using .then
gives me the data from the fulfilled promise by waiting for it to be received. We put the cherry on top in
app.js
by calling fetch
along with .then
to get the response data. // Now we send our request! fetch(url, options) // Fetch is promised based -- the promise is not fulfilled yet... .then(response => response.json()) // Now the promise is fulfilled! Let's take a look at the response! .then(json => { console.log(json); }) // Best practice to do error catching! .catch(console.error);
If you'd like to see the entirety of
app.js
, check out the repository!๐ That's a wrap folks!
Thanks for reading, and I hoped this opens opportunities for you to build helpful tools using innovative APIs.
An aside...
If you like how innovative GraphQL is with making complex things simple, I highly suggest you check out FastAPI! FastAPI is a python web framework that helps you create production-ready web apps without needless hoops. You can easily implement your own GraphQL endpoint too!