GraphQL for Beginners: Subscriptions, Schemas and Servers
15 July, 2022
12
12
0
Contributors
Welcome back to GraphQL for Beginners! A beginner-friendly series introducing 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 be able to build a simple chat app with GraphQL, React and Apollo.
Sneak Peek:
If you haven't read Part 1, please do so here.
Subscriptions
In Part 1, we learnt about the 2 operations GraphQL supports: queries and mutations. The third type is known as subscriptions.
Subscriptions are the operation used to push data from the server to the client on a specified event. Like queries, they fetch data and return it, but only when a certain change happens. Thus, subscriptions work by having an active connection to your GraphQL server (i.e. via WebSocket), where it will listen for a particular event and return data when the event is triggered.
How it Works
Let's go back to our Snow Tooth Ski Resort API example found at: https://snowtooth.moonhighway.com/.
In the Docs panel, under Subscriptions, we can see that this API has 2 subscription operations available. Let's click on the LiftStatusChange
, which listens for a status change in a Lift and returns that Lift object.
Let's first subscribe to this operation then make a change to a Lift's status to see how the subscription works.
In the image below, we can see that on clicking the execute button, the operation keeps running and the word 'Listening' is shown at the bottom to indicate that the subscription is now actively waiting for a LiftStatusChange
event.
Now let's use the mutation setLiftStatus
to change the status of a Lift.
Read Part 1 for more details on mutations
In this example, I changed the Lift with the id astra-express
to a status of HOLD. Back in the subscription tab, you will see that a data object has been returned because a Lift status change was detected by the listener.
And it correctly returns the data of the Lift which status was changed: astra-express
.
Why use subscriptions?
Subscriptions are useful so that we can update data to our client in real-time.
In the context of the chat app we will build, using queries would mean we need to fetch and return chat data each time the user post a message. Instead, subscriptions will allow the newly posted message to return automatically when the listener detects a new message is posted.
Schemas
So far, we've learned about GraphQL queries, mutations and subscriptions from existing GraphQL APIs such as the hashnode API and Snow Tooth Ski Resort API.
For our chat app, we will need to build our own GraphQL API from scratch. To do that, we need to define a Schema. A schema is the blueprint of a GraphQL API. It defines the types and interactions between them that makes up the API. Learning the Schema Definition Language (SDL) will allow you to make robust type systems for your GraphQL APIs.
It's all about the types
To construct the schema, we first need to define the category of the type. Types can be one of the following categories:
1. Scalar types
Recap from Part 1 of this series, scalar types are ID, Float, Int, String or Boolean.
2. Object types
Types with their own properties (fields) and each field also have their own type.
3. Query type
Entry point to make queries and defines the data to return from that query.
4. Mutation type
Entry point to create or update data, then return specified data.
5. Subscription type
Entry point to allow subscription to a certain event or change in specific data.
6. Enum types
Predefined and restricted list of options for the type's value.
7. Input types
Allows passing an object as an argument for queries/mutations.
8. Union types
Allows a field to return one or more object types.
9. Interface types
A set of properties (fields) that can be implemented by one or more object types.
An Example
Our Snow Tooth Ski Resort API has a Lift object type. Its type would be defined in the schema. The Docs panel shows what the type looks like.
We can see that some of its properties like id
and name
are scalar types. While others like status
returns LiftStatus
, an enum type.
Square brackets indicate that the returned value will be an array. So trailAccess
returns an array of Trail types. And the Trail type is an object type with its own properties.
SDL Cheat Sheet
In the next part of this series, we will learn how to build our own schema for our chat app project. For now, you can briefly scan this helpful SDL cheat sheet.
Servers
In order for the client-side to query for data from a GraphQL API, a GraphQL server would be an easy and common solution. It consists of 2 things:
- A GraphQL schema
- Resolver functions
As mentioned before, the schema describes the types in the API (i.e. type name, its properties and the type of each property).
Resolver functions are the ones that tell the API what and how data is returned in each property of the type. Hence, each property (field) in the schema is backed by a resolver function that is responsible for returning the data in that field.
An Example
In the Snow Tooth API, there's a query type allLifts
that returns an array of Lift objects. The type schema would look like:
The field allLifts
will have a resolver function like so:
We will learn how to construct resolver functions more in detail as we build our chat app. This is just the general concept of how a GraphQL server and its resolver functions work.
Choosing your GraphQL server
There are many options to set up a GraphQL server. This article compares the 3 most common choices for GraphQL servers:
- express + express-graphql + graphql
- apollo-server + graphql
- graphql-yoga
In the next parts of this series, we will use graphql-yoga
to set up the chat app's GraphQL server. But feel free to explore the different options and try them out yourself in your free time.
To Be Continued
Thanks for reading this article. I hope it has been helpful so far. Now that we finally learned all the concepts about GraphQL we need for this project, in the next part, we will start building our chat app!
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. Stay tuned!