GraphQL 101: Validation and Execution

So far we've covered an overview of GraphQL, the Query Language, and the Type System. Now, let's take a look at how we validate queries and how queries are executed.

The schema covered in the Type System post is used by a GraphQL server to validate queries from clients or applications. Usually, the server will validate a query before executing it. There are circumstances under which the server doesn't validate before execution, for example:

  • it recognizes that an identical request has been previously validated, or
  • the requests were validated during development.

Validation

Most developers use libraries to accomplish validation like GraphQL Inspector. However, if you want to build your own validation library the specification provides algorithms for each part of the query. Links to those algorithms in the spec are below. The numbers refer to the section of the spec where the algorithms are found.

You will likely recognize this list from Parts 1 and 2 of the Query Language. Since the server is validating clients' queries it makes sense the descriptions would be found in the Query Language.

Only after the server has validated a client query, it is then executed.

Execution

Execution is the process by which a GraphQL server generates a response to a request. When the server receives a query from a client, it validates that request and then executes it by calling resolvers. The server will package values generated by resolvers and any errors that may have been thrown from resolver functions as the response returned to a client.

Just as with validation, the spec provides algorithms for each part of an execution.

Let's take a closer look at the key components of execution.

  • Resolvers
  • Response Format
  • Errors

Resolvers

Resolvers are functions that return the value for each field on each object in a GraphQL query.

"It is common for resolver to be asynchronous due to relying on reading an underlying database or networked service to produce a value. This necessitates the rest of a GraphQL executor to handle an asynchronous execution flow." - the spec

The server library that contains the execution engine calls the resolvers which provide four arguments: object, arguments, context, and info.

Response Format

A GraphQL response is a map, and it’s usually serialized as JSON. A response may include three different keys that will be included in the response.

  • data: if the execution was successful and contains data
  • error: if error(s) occurred during execution
  • extension: if there are objects which contain features beyond what the spec prescribes
{
  "data": {
    ...
  },
  "errors": [
    {
      "message": ...,
    }
  ],
  "extensions": {
    ...
  }
}

Errors

In the above example response, the error only has a single key, message. Often, there are more keys. Other keys may be present such as: locations, path, and extemsions.

Locations

"If an error can be associated to a particular point in the requested GraphQL document, it should contain an entry with the key locations and a list of locations, where each location is a map with the keys line and column, both positive numbers starting from 1 that describe the beginning of an associated syntax element."

Path

If an error can be associated with a particular field in the GraphQL result, it must contain an entry with the key path that details the path of the response field which experienced the error. This allows clients to identify whether a null result is intentional or caused by a runtime error.

Extensions

The extensions key is for adding fields beyond those in the spec. Commonly added fields are code and timestamp.

Summary

We've covered all parts of GraphQL Specification. In the next article, we'll look deeper at some example queries and responses. And we'll then consider what it means to make the shift to GraphQL and how to think in graphs.