GraphQL for Beginners: Introduction

GraphQL for Beginners: Introduction

Let's build a real-time chat app with GraphQL, React and Apollo! Step-by-step tutorial for beginners ๐Ÿ”ฐ Part 1: Introduction to GraphQL

Welcome to GraphQL for Beginners! The primary goal of this series is to introduce the basic concepts of GraphQL and how to connect it to a front-end framework like React using Apollo. At the end of this series, you will have a simple chat app built with GraphQL, React and Apollo.

Sneak Peek: demo.gif

Prerequisites

  • No prior knowledge in GraphQL and Apollo needed
  • Any code editor
  • Intermediate-beginner experience with React, JavaScript
  • For Windows: Git and Git Bash installed
  • Optional: Get GraphQL in VS Code extension for syntax highlighting

image.png Click on image to download the extension.

Introduction to GraphQL

Before we even start building the app, we need to learn the technologies we will be using. In particular, GraphQL.

What is GraphQL?

GraphQL is a query language for APIs. It was developed by Facebook as a solution to fetch data more efficiently.

Why GraphQL: The Problems with REST

In REST APIs, each endpoint will return a specific payload of JSON data. Even if we only need certain fields, it will return everything on every request.

Take a look at the endpoint (pokeapi.co/api/v2/pokemon/ditto) in PokeAPI (A RESTful API for Pokemon):

image.png

The returned chunk of data is very large, and most of the time, an app probably doesn't need all these data.

Also, the design of REST APIs may require an app to make a lot of unnecessary requests because some data may be from different endpoints. Going back to the PokeAPI, we can see that under abilities, there are URLs to get more specific data on each ability.

This means, in order to retrieve data about a single Pokemon's abilities, you need to make 3 HTTP requests:

  1. https://pokeapi.co/api/v2/pokemon/ditto to get its abilities
  2. https://pokeapi.co/api/v2/ability/7/ to get info on ability 1
  3. https://pokeapi.co/api/v2/ability/150/ to get info on ability 2

As demand for faster and more efficient apps increase among its users, Facebook recognized these issues in REST APIs. In 2012, it began developing GraphQL internally before releasing it to the public in 2015.

Let's take a look at how GraphQL solves the issues of REST APIs and more.

How GraphQL Works

As mentioned before it is a query language, which means it fetches only the data you need using queries. With GraphQL, there is:

  • No overfetching or underfetching
  • Less endpoints to manage (i.e. only /graphql)
  • Flexible integration with database, a REST API, a cloud service, and a JSON file

image.png

A typical GraphQL operation goes like this:

  1. Data is requested from the GraphQL server via a query.
  2. A function is called on the GraphQL server to get data from the appropriate source.
  3. The GraphQL server returns a response to the client.

GraphQL comes with an IDE called GraphiQL that is helpful for developers to test the API. The very first GraphQL API (SWAPI) uses GraphiQL.

image.png

Alternative IDEs such as the GraphQL Playground is developed and maintained by Prisma. This is the one the Hashnode API is currently using.

Queries

Now that we know how GraphQL works, let's learn how to construct a query using Hashnode's API as an example.

The API Playground can be found at api.hashnode.com.

Every GraphQL IDE has access to a Docs panel. This is the API documentation that is generated when a GraphQL API is built. It is a useful panel so that any developer, even those who never uses the API, can immediately understand what the API can do.

In the Hashnode API, we can click on the 'Docs' button on the right to open the panel.

image.png

We can see a few lines under Queries such as user(...), storiesFeed(...), etc. These are the available query commands that this API can execute.

Let's try writing a query for user(...). Click on it to learn more about this query. You will see something like the image below.

query.PNG

We can see that this query accepts a username as a required (non-nullable) argument. It is required because there is an exclamation mark next to it. If there's no exclamation mark, it is nullable (optional).

Next, this query will return a User type based on the supplied username. Below are the properties of User that you can choose to be returned. Unlike REST APIs, the returned User type doesn't need to include all its properties. You can just query the ones you want.

Let's say we want to fetch the name, dateJoined, numFollowers of my blog. My username is victoria. The query for this will be:

//any query must start with the query keyword
query{ 
  //write the query according to the format in the docs
  user(username:"victoria"){ //supply the username arg as a String
    //include the properties you want to get
    name
    dateJoined
    numFollowers
  }
}

Now let's execute this query in the Playground: query.gif

And ta-da! The API returns a JSON with the exact data we wanted. No more, no less. This is the beauty of GraphQL indeed.

Scalar vs. Object Types

In the example above, our returned data is a User type. User is an object type because it has properties that you can further query.

The properties we queried earlier (name, dateJoined and numFollowers) have a type too, such as String and Int. These are scalar types. Scalar types consists of 6 categories:

  • ID
  • Float
  • Int
  • String
  • Boolean

An object type like User can have scalar type properties or object type properties or both. Back in the docs, we can see that User has 2 object type properties: SocialMedia and Publication. If we click on SocialMedia, we can see the object's properties that we can query further.

obj.PNG

Let's try querying a User's SocialMedia's twitter, github and website properties.

image.png

The query works perfectly. This time, we have a deeper nested query as we first have to query User, then socialMedia and finally, the properties we want.

And that's the gist of queries. Of course, there are more details on queries that is out of this series' scope, so please feel free to browse the 'Read More' section at the end of this article. I have included some really amazingly written resources if you'd like to learn more on your own.

Mutations

The next important concept about GraphQL is mutation. If a Query is equivalent to a GET request in REST, then a Mutation is like a POST request.

Essentially, they are written like queries do. The only difference is that it is used to make changes to the back-end data.

To illustrate mutations, let's use another GraphQL API called Snowtooth (Ski Resort) API.

In the Docs, we can see the available mutations for this API under Mutations. Let's click on setLiftStatus(...) to see what it can do.

post.PNG

As shown in the image above, this mutation allows us to change the LiftStatus property of a Lift object type by supplying the its id and LiftStatus properties as arguments.

Notice that LiftStatus is not a scalar type. If we click on it, we can see that it is an enum that only be one of the values: OPEN, CLOSED or HOLD. This is important to note so that we don't supply a random String as its value or it will return an error.

So to perform this mutation, let's query allLifts to get the id of a random Lift. As seen below, allLifts takes an optional LiftStatus argument (because no exclamation mark).

allLifts.PNG

We make a simple query to get allLifts with a LiftStatus of OPEN and get their id property.

image.png

Then, let's take a random id from the returned list for our mutation. I choose astra-express for this example.

Now, we have all the arguments we need to write the mutation to change the status of astra-express from OPEN to CLOSED like so:

//every mutation must start with the mutaion keyword
mutation{
  //supply the appropriate arguments
  setLiftStatus(id:"astra-express", status:CLOSED){
    //return the following properties after the mutation
    id
    name
    status
  }
}

And the result of the mutation will show that the astra-express Lift now has a status of CLOSED.

image.png

And that's how we can perform a mutation. Pretty straightforward like queries, isn't it?

To Be Continued

Thanks for reading this article. I hope it has been helpful so far. It is getting quite long so let us continue in the next part, where we will learn GraphQL Schemas, Subscriptions and Servers.

In the meantime, please have a look at the Read More section below if you want to explore the concepts in this article a little more deeply. Cheers!


Read More

Did you find this article valuable?

Support Victoria Lo by becoming a sponsor. Any amount is appreciated!

ย