Note: This article assumes a basic familiarity with GraphQL as a query language.
GraphQL.org defines GraphQL as
... a query language for APIs and a runtime for fulfilling those queries with your existing data.
Most resources focus on how to use GraphQL as a query language. But what does it mean for GraphQL to be a runtime?
Let's start with the fundamentals and review the definition of a runtime.
It's important to note that there are two meanings of 'runtime' broadly present in the tech vernacular.
The first is: the time during which your program executes. That's not what we're talking about in this blog post.
The second meaning, which we are going to focus on, refers to the environment in which your program executes. It's good to note that the runtime is determined by the GraphQL spec, which sets a global standard for GraphQL implementation between developers.
When you create a GraphQL query, you expect a response. You get a response because of the way the GraphQL runtime executes your request. The runtime's higher level of abstraction is what allows us to use GraphQL at all.
process.env. Similarly, when you write a GraphQL query, GraphQL's runtime is at work.
We'll get into the nitty gritty of GraphQL's runtime in particular next.
The GraphQL spec, as a set of rules that delineates GraphQL conventions, has a lot of details, so I've condensed the logic a bit in my summary.
First, a request for execution includes some information. It must include a document with an OperationDefinition and optionally a FragmentDefinition, and there may be multiple instances of those. Beyond that, it may include the name of the operation in the document to execute and the variable values in the operation. The request also must know what the root type (
query myQuery, e.g.) is.
We zoom out even further for the next step, in which GraphQL will validate the request, and coerce any variables (if present).
Now the GraphQL runtime identifies whether the operation is a query, mutation, or subscription.
Subscriptions trigger event streams and return response streams, while mutations and queries return ordered maps containing data and errors.
The selection sets of fields inside operations undergo a process through which they are executed either normally or serially. The runtime determines the field collection, and then the field execution, which is complete when each field has been coerced, and its values resolved and completed.
These values, along with any errors that may be thrown, form the response.
StepZen's engineers work with GraphQL as a runtime to create new features in GraphQL as a query language.
Take, for example, StepZen's custom
@materializer combines data from two types into one, allowing you to martial data from multiple different backends, and multiple different types of backends. StepZen has a selection walker implementation that allows
@materializer to resolve the correct fields for the query.
To accomplish the same thing without StepZen, you'd would have to spend time writing custom resolvers to call the backend service correctly.
By adding a custom directive like
@materializer, you can give your frontend developers the ability to retrieve data from, say, your PostGreSQL database and your CMS's REST API in a single query. Adding a GraphQL layer can be a complex undertaking, but StepZen simplifies it by polishing the runtime with things like custom directives and scalar types.
Since StepZen considers GraphQL both as a query language and as a runtime, we are able to leverage GraphQL queries powerfully, which saves you valuable time when it comes to using GraphQL as a query language.