The schema is the contract every client and server tool relies on.
Schemas are written in the Schema Definition Language (SDL). The entry points are the root types Query, Mutation and Subscription; everything else is reachable from them.
type Query { book(id: ID!): Book books: [Book!]! }
type Book { id: ID! title: String! pages: Int genre: Genre }
enum Genre { FICTION SCIENCE HISTORY }The building blocks:
- Scalars:
Int(32-bit),Float,String,Boolean,ID(serialized as a string, meant for identifiers). Servers can add custom scalars likeDateTime. - Object types have fields; each field has a type and optional arguments.
- Enums restrict a value to a fixed set.
- Lists
[T]and non-nullT!wrap other types.
Non-null placement matters: [Book!]! means the list itself is never null and contains no null items; [Book] allows both a null list and null items.
Fields are nullable by default. That is deliberate: if resolving a nullable field fails, the server can return null for that field and still deliver the rest of the response. Mark a field ! only when you can always produce it.
Descriptions are written as strings before a definition ("The book's ISBN-13") and show up in documentation tools.
Example
"A book in the catalogue"
type Book {
id: ID!
title: String!
"Number of pages; null if unknown"
pages: Int
genre: Genre
tags: [String!]! # never null, items never null (may be empty)
}
enum Genre { FICTION SCIENCE HISTORY }
type Query {
book(id: ID!): Book # nullable: null when not found
books(genre: Genre): [Book!]!
}Remember
- Root types Query, Mutation, Subscription are the entry points
- Five built-in scalars: Int, Float, String, Boolean, ID
- Fields are nullable by default;
!makes a promise
Watch out for
- Marking everything non-null, so one failing field nulls out its whole parent.