Skip to main content

GraphQL API

This guide was heavily influenced by https://graphql.org/learn/best-practices/

Overview

  • Who is the audience for this guide
  • Who is the audience for the API

Principles

One of the most important things to keep in mind when building a GraphQL API is that GraphQL is not REST. In particular, GraphQL is most powerful when used as a way to model your problem domain. This is probably not an exact 1:1 mapping with your database models.

GraphQL is ... a graph. Graphs offer a different way of thinking or modeling your data than you may be used to.

See also GraphQL Rules for additional recommendations and best practices

Building GraphQL APIs

Schema First

Prefer schema first tooling that allows producers and consumers agree upon a data shape prior to implementation. This allows a discussion about the problem domain that is independent of the technology being used on either side of the API.

By designing your GraphQL schema to fit the way you want to think about the data instead of your implementation, you can evolve your implementation without changing clients.

Versioning and Backwards Compatibility

The Versioning section of GraphQL Best Practices describes why GraphQL APIs should be backwards compatible and not versioned. Building Evolvable Schemas has some concrete advice on how to structure your schema.

Nullability also influences schema evolution, so think carefully about which fields to require.

Mutations Communicate Intent

GraphQL mutations should be specific enough to communicate the intent of the change. Avoid anemic mutations

Errors and Nullability

GraphQL is designed for returning as much data as possible, even if an error occurs. That can be surprising, and surprisingly powerful.

That means both data and errors can be returned.

Pagination

Pagination can heavily influence schema design. The concept of GraphQL Connections is yet another new and powerful concept to grasp when designing a schema. By thinking about this early, you can avoid having to make breaking changes to your schema.

Simplicity is nice when first starting out and prototyping, but it is strongly recommended to use the connection concept when using the schema in production.

Caching

GraphQL prefers to use GUID for objects to facilitate Caching.

Errors

Error handling in GraphQL is not fully standardized.

Some folks are using unions and interfaces to handle errors to encode errors in the response data instead of in the basically untyped errors field. This makes the most sense for errors that are specific to the operation being made that you want the client to handle gracefully. It also encourages you to include errors as part of your domain modeling, which is a good thing.

Tooling

Using a schema linter (such as graphql-schema-linter) and running it as part of your pre-commit checks is recommended. Some of the defaults of such linters may be optimized for large public APIs and should be adjusted to best suit your project.