Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save dburles/6b6b1d1919d81bfeee7f30b2d1e449fe to your computer and use it in GitHub Desktop.
Save dburles/6b6b1d1919d81bfeee7f30b2d1e449fe to your computer and use it in GitHub Desktop.
An approach to designing REST API’s to optimise requests made from a GraphQL server in combination with DataLoader.

Optimal REST API design for GraphQL with DataLoader

This document outlines an approach to designing REST API’s to optimise requests made from a GraphQL server in combination with DataLoader.

Entity relationships

Entities should always include their own id.

One-to-one relationships should be exposed through a field on the entity and never through denormalisation.

One/many-to-many relationships should not be exposed through an array on the entity, but instead through a List endpoint.

Entity endpoints

As the name suggests, these endpoints are for loading entities. The key component is their ability to batch up and load multiple entities in a single request; avoiding the n+1 problem. For any entity that exists in a system that should be exposed, a corresponding entity endpoint should be made available.

These endpoints must accept one or more id query parameters, e.g., /book?id=1&id=2&id=3 .

Any entity that cannot be accessed, (e.g., permissions), should be filtered from the response, rather than resulting in an error.

List endpoints

List endpoints produce lists of entities. Any relationships that exist should be exposed through an id and not through denormalisation. For example, a list of books (/books):

[
  {
    id: "7c14883b",
    authorId: "a9bf4d69",
    title: "Book One"
  },
  {
    id: "e11cc805",
    authorId: "681c56ba",
    title: "Book Two"
  },
  ...
]

The relationships from books to authors can then be connected through a single batched request to the /author entity endpoint, e.g., /author?id=1&id=2.

Another important consideration of a List endpoint is that it should always return the exact same set of fields as its corresponding Entity endpoint. That way, the related Entity DataLoader cache can be primed.

Additional considerations

Ideally all List endpoints should support filtering and pagination to maintain consistency across the REST API as well as the GraphQL schema.

List and Entity endpoints should not be combined into a single endpoint as pagination and batching parameters are incompatible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment