GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data, developed by Facebook in 2012 and open sourced in 2015. The goal was to create a query language that allowed fine-grained control over the needed data a client can request to an API server.
A GraphQL service is created by defining types and fields to those types in a schema. A commom way to defining the schema of your GraphQL service is through the GraphQL Schema Definition Language (SDL).
In this article, I'll show how to create a GraphQL schema compliant with the Relay GraphQL Server specification.
Defining your schema in GraphQL
A GraphQL schema should informe the users about all the types and objects that can be queried and mutated on the graph. GraphQL even provides a feature to query metadata about those types and objects, which can be used to document the GraphQL.
Let's define a simple schema using GraphQL SDL (Schema Definition Language):
- First we define a custom Date scalar that should validate and serialize Date objects;
- We define a
Nodeinterface. I'll explain more on why I'm defining this interface the next topic;
- We define an enumeration type to define the valid priority status of a task;
- We create our
Tasktype with all the field it should contain. Notice that all field with the exclamation mark at the end are obligatory;
- We add an input called
AddTaskInputthat defines the obligatory data to add a new
- In the Query type (which is a GraphQL reserved type), we define what queries are available from our root object;
- In the Mutation type (which is a GraphQL reserved type), we define which operations to alter our data are available. Such operations are called mutations.
Notice that, in GraphQL, comments between quotes serve as documentation (it'll be parsed and displayed in your GraphiQL web documentation interface), while the comments that start with
# are ignored.
Querying your data in GraphQL
Tipically, you'd query a GraphQL server like this:
Which would return the following, in JSON format:
In the query above, we started with a special "root" object, from where we select the
task field with the id equals to
2 Then, we select the
title field from the
task object. But, if no task has an id equals to 2? In this case, our response would be:
Or, in case of a error, we would receive this response:
You may want rename a field before using your data. Well, you can create your aliases just like this:
And that would be the return:
GraphQL also provides the feature of create query fragments and setting up directives to query your data. I'll need to add more complexity to our current schema in order to explain that, so, for while, let's move to the next topic.
The Relay GraphQL Server specification
Despite you may not want to use Relay (or even React) to consume your GraphQL data, their specification is very useful and provides a common ground of what developers should expect from a GraphQL server.
Node interface we defined above? Its purpose is to provide a global object identification for all the GraphQL nodes in our server. Therefore, a GraphQL client can handle re-fetching and caching in a more standardized way. Notice that each ID must be globally unique on your application.
Node interface will be used for all objects in our server, GraphQL provides a reusable unit called fragment. Now, let's add a new way the query nodes on our schema:
Notice that the
task query was removed, as it is no more needed. And now, we will re-do our query using a fragment:
And now, we will change our schema to comply with the Relay GraphQL Server specification. Take some time to read the comments in order to understand what is being done here.
At this point, the metaphor of graphs used here should be very clear. Each edge of your graph has a node and a connection of edges has a collection of nodes that can be paginated. Note that, in this specification, is expected that you implement a cursor based pagination, rather than a offset pagination (follow the previous link to have more information about their differences.
And that's all we need to comply with the Relay GraphQL Server Specification.
In the next article, I'll implement a GraphQL server using all the concepts that we learned here.