This article's content
Design decisions in GraphQL

Things to consider when creating/changing the schema

All of the following schema changes are potentially breaking changes:

  • Removing a type or field
  • Renaming a type or field
  • Adding nullability to a field
  • Removing a field’s arguments
  • It’s easier and safer to add a new field to a schema than it is to remove an existing field that some of your clients are using.

Query driven design

Design your schema based on how data is used (aka Query-driven schema design), not based on how it’s stored.

If your client wants to query that:

query EventList {
  upcomingEvents {
    location {
      weather {

Then your schema could look like that:

type Query {
  upcomingEvents: [Event!]!

type Event {
  name: String!
  date: String!
  location: Location

type Location {
  name: String!
  weather: WeatherInfo

type WeatherInfo {
  temperature: Float
  description: String

Naming conventions

  • Field names should use camelCase
  • Type names should use PascalCase
  • Enum names should use PascalCase
  • Enum values should use ALL_CAPS

In GraphQL, it’s recommended for every mutation’s response to include the data that the mutation modified. This enables clients to obtain the latest persisted data without needing to send a followup query.

Error handling

Mutations are much more likely than queries to cause errors, because they modify data. A mutation might even result in a partial error, in which it successfully modifies one piece of data and fails to modify another. It is recommended to define a MutationResponse interface in your schema.

interface MutationResponse {
  code: String!
  success: Boolean!
  message: String!

and implemented:

type UpdateUserEmailMutationResponse implements MutationResponse {
  code: String!
  success: Boolean!
  message: String!
  user: User

Descriptions (docstrings)

"Description for the type"
type MyObjectType {
  Description for field
  Supports **multi-line** description for your [API](!
  myField: String!

    "Description for argument"
    arg: Int

About Author

Mathias Bothe To my job profile

I am Mathias, born 40 years ago in Heidelberg, Germany. Today I am living in Munich and Stockholm. I am a passionate IT freelancer with more than 16 years experience in programming, especially in developing web based applications for companies that range from small startups to the big players out there. I am founder of, creator of the security service platform BosyProtect© and initiator of several other software projects.