Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
The Schema  ›  Lesson

Objects, Lists and Non-Null

Objects 14 minObject types group typed fields that may take their own arguments, list and non-null wrappers combine to say whether a list and its items can be null, and a null in a non-null position moves up to the nearest nullable parent.

Objects, Lists and Non-Null

A book has one author and many reviews. Some books have no reviews yet; a book without an author should never exist. A schema captures all of that in a few characters, and reading those characters correctly tells you exactly what null the client might ever see.

The rule

! means never null; read list types from the outside in.

An object type is a named set of fields, each with a type and optionally its own arguments:

type Book {
  id: ID!
  title: String!
  genre: Genre!
  author: Author!
  reviews(first: Int = 5): [Review!]!
  subtitle: String
}
  • subtitle: String may be null (many books have none).
  • author: Author! is never null.
  • reviews(first: Int = 5) is a field argument with a default; reviews { rating } returns up to five.

For lists, the two positions of ! mean different things. Read from the outside in: first "can the list be null?", then "can an item be null?"

Type List null? Item null? Allowed values
[Review] yes yes null, [], [r1, null]
[Review]! no yes [], [r1, null]
[Review!] yes no null, [], [r1]
[Review!]! no no [], [r1, r2]

[Review!]! is the usual choice for "zero or more reviews": the client can loop without null checks. An empty list is still allowed.

A ! is a promise, and if a resolver breaks it, GraphQL does not send the forbidden null. Instead, the null moves up to the nearest parent that is allowed to be null, and an error explains why. If Book.author fails for b1, then book itself becomes null, because Query.book returns a nullable Book. Mark fields non-null when they truly always exist; overusing ! lets one failure blank out large parts of a response.

One convenience on input: if an argument expects a list, such as ids: [ID!]!, and you pass a single value "b1", it is treated as ["b1"].

The shortcut

To read any field type, say it aloud from the outside in: "a non-null list of non-null reviews" for [Review!]!. Then list which values that sentence allows.

When Book.author failsStep 1 of 4
  1. The query

    { book(id: "b1") { title author { name } } }

Drills

Answer fast — trust the rule.

quick drill

Which type means "always a list, possibly empty, with no null items"?

quick drill

Which value is allowed for a field of type [Review]!?

quick drill

Book.author is Author! and fails for b1. Query.book returns Book. What is data.book?

quick drill

With reviews(first: Int = 5): [Review!]!, how many reviews can book(id: "b1") { reviews { rating } } return at most?

Remember

  • ! means never null; read list types from the outside in.
  • Say the type aloud ("a non-null list of non-null reviews"), then list the allowed values.
  • Trap: a broken ! promise nulls the nearest nullable parent, so do not overuse !.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainChoose the nullability

Author gets two new fields: awards, a list of award names that is empty for most authors, and website, which many authors do not have. Choose a type for each, justify every ! you use or leave out, and explain what would happen to a query if a field you marked non-null failed.