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 {
    name
    date
    location {
      name
      weather {
        temperature
        description
      }
    }
  }
}

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](http://example.com)!
  """
  myField: String!

  otherField(
    "Description for argument"
    arg: Int
  )
}

About Author

Mathias Bothe To my job profile

I am Mathias from Heidelberg, Germany. I am a passionate IT freelancer with 15+ years experience in programming, especially in developing web based applications for companies that range from small startups to the big players out there. I create Bosycom and initiated several software projects.