My first experience with GraphQL was a long time ago when I was building a website in Gatsby:
I played with the explorer briefly, but decided I didn’t need much of this feature at the time. Without further investigation, I remembered GraphQL as a query language for data fetching, which is similar to REST in that regard. One difference if that with GraphQL, you have the flexibility to ask for specific data and the server will return the exact data that was asked; whereas when working with RESTful APIs, you get a set amount of data from an endpoint, which could be a lot more or less than what is really needed.
Recently, I worked on some docs around the topic of rate limiting in GraphQL, so I got to play with it a bit more.
In this blog, we will first go over how GraphQL came about, followed by the basics of GraphQL queries, mutations, and subscriptions.
What is GraphQL
GraphQL is an open-source query language and runtime for APIs that was built at Facebook:
…we needed a data-fetching API powerful enough to describe all of Facebook, yet simple enough to be easy to learn and use by our product developers.
…we evaluated our options for delivering News Feed data to our mobile apps, including RESTful server resources and FQL tables (Facebook’s SQL-like API). We were frustrated with the differences between the data we wanted to use in our apps and the server queries they required. We don’t think of data in terms of resource URLs, secondary keys, or join tables; we think about it in terms of a graph of objects and the models we ultimately use in our apps like NSObjects or JSON.
GraphQL was given birth. It provides a declarative syntax for clients to request the precise data they need from a server. Unlike traditional RESTful APIs, where each endpoint corresponds to a fixed set of data, GraphQL allows clients to define the structure of the response they require. This flexibility empowers clients to retrieve multiple resources in a single request, eliminating issues like over-fetching and under-fetching of data.
GraphQL Query, Mutation, and Subscription
GraphQL queries, mutations, and subscriptions should be first defined on the server side before the client side can interact with the server.
- GraphQL Server: responsible for implementing the resolver functions that handle the actual execution of the queries, mutations, and subscriptions defined in the schema.
- GraphQL Client: clients can then construct GraphQL queries, mutations, or subscriptions and send them to the server for getting or modifying data.
The following learnings use the GitHub GraphQL API and provide examples of how you can construct client-side queries, mutations, or subscriptions.
To follow along, you can log in to the GitHub GraphQL explorer and run your GraphQL operations there. This uses the quota of your GitHub account.
Alternatively if you prefer to work on the terminal, you can create a GitHub personal access token with the appropriate scopes for the resources you want to interact with, and use it to send requests to the GitHub GraphQL API endpoints, with the GraphQL operations you would like to perform.
GraphQL Query
GraphQL queries are used to retrieve data from the server. They are analogous to HTTP GET requests.
For example, you can query the name and description of the hello-world repository owned by octocat:
query RepoByOctocat {
repository(owner:"octocat", name:"hello-world") {
name
description
}
}
You should see the following response:
{
"data": {
"repository": {
"name": "Hello-World",
"description": "My first repository on GitHub!"
}
}
}
GraphQL Mutation
GraphQL mutations are used for modifying data on the server. They are analogous to HTTP POST, PUT, or DELETE requests. They enable clients to create, update, or delete data by specifying the required changes in the request.
For example, this sample mutation adds a hooray emoji (🎉) to a subject with the specified ID. This subject corresponds to issue 349 in the hello-world repository:
mutation AddReactionToIssue {
addReaction(input:{subjectId:"MDU6SXNzdWUyMzEzOTE1NTE=",content:HOORAY}) {
reaction {
content
}
}
}
You should get a response similar to the following:
{
"data": {
"addReaction": {
"reaction": {
"content": "HOORAY"
}
}
}
}
This confirms the emoji was added.
GraphQL Subscriptions
GraphQL subscriptions introduce real-time capabilities to the GraphQL ecosystem and allow for even-based updates. They are similar to GraphQL queries in that they specify fields of data to be returned, but instead of immediately getting the response, the response is sent automatically by the server when the subscribed event occurs. This is particularly useful for building applications that require live data updates.
Not every GraphQL schema has subscription defined. If you runs a subscription against a schema that does not have subscription configured, you get an error similar to the following:
{
"errors": [
{
...,
"extensions": {
"code": "missingSubscriptionConfiguration"
},
...
"message": "Schema is not configured for subscriptions"
}
]
}
Unfortunately, I could not seem to find an example with the Github GraphQL API that supports subscription. See Apollo’s Defining a subscription for how to enable a subscription on the server side and how to construct a subscription on the client side.
Final Words
I chose to not make a section to analyze reasons why you should or should not use GraphQL over RESTful APIs, simply because there is never a one-size-fits-all solution. Both technologies have their benefits and drawbacks, depending on the use cases and implementations of your applications.
However, you could start your evaluation with the following considerations:
- self-documenting capability
- data retrieval efficiency
- API design and versioning
- query flexibility
- typing system
- readability
I encourage you to explore additional resources. Here are a few to start with:
- GitHub GraphQL API documentation
- Facebook Graph API
- Free to Use Public GraphQL APIs, available in Apollo studio.
- Why Gatsby Uses GraphQL
- Apollo supergraph demo, the federated graphs.
Bonne lecture!