Context

GraphQL relies on a schema to act as a contract between the server and a client. Basically, it answers the questions ‘What can I ask for?’ and ‘What can I get?’. Fields in the schema can be specified as ‘non-null’ which means that the value will never be null. This is useful information for the client. In designing the schema, it requires extra consideration of the data model to imagine what fields could realistically be missing from the response.

One of the strengths of GraphQL is the ability to return partial responses when the client requests multiple resources. If every field in the schema is marked as non-null, then any error will result in a { data: null, errors: [...] } response.

The Process

  • The GraphQL spec on data/errors
    • If the field which experienced an error was declared as Non-Null, the null result will bubble up to the next nullable field.

  • What Apollo has to say about nullability
    • I would say static type code generation is one of the main benefits of taking advantage of the non-null feature in GraphQL

    • In object type fields where the data is fetched from a separate data source. I’d suggest making any fields that have resolvers that fetch asynchronous data nullable, so that it’s easier to deal with errors that result from a service or database being unreachable.

    • I almost always recommend setting the items inside the list to be non-null

    • I think choosing nullable as the default for GraphQL fields was a good decision, and that making too much of your GraphQL schema non-null can be a risky proposition if you don’t think ahead.

  • When to Use GraphQL Non-Null Fields

Conclusion

Where most strongly typed languages prefer nonnullable values, GQL takes the opposite approach. By default, all values are nullable and can be marked as non-nullable (With a ! appended to the data type in the schema). This is because most strongly typed languages exist within a closed system. Consumers of a Java server don’t need to adhere to its type system. GQL is designed to be compatible with a wide range of clients in a variety of contexts, so it prefers to err on the side of flexibility.

To answer the question, values we can guarantee from systems we control should be nonnullable. Queries that rely on a response from a third party service should not be mandatory. My instinct is to express confidence that a field will exist, but GQL’s null bubbling can obliterate useful data from other queries if a non-null field errors out.

The last point that doesn’t really apply to my situation is how non-null fields affect ongoing server development. For example, turning a nullable query argument into non-null, or a non-null response field into nullable, are breaking changes that could cause problems. This is exacerbated by GQL’s resistance to API versioning.