Schema-First-Design
GraphQL beginnt mit einem typisierten Schema (SDL): Objekttypen, Queries und der Vertrag, den Client und Server teilen.
Deutsche Übersetzung in Arbeit
Diese Lektion ist noch nicht ins Deutsche übersetzt und wird daher auf Englisch angezeigt. Der Rest der Seite ist vollständig lokalisiert.
Auf dieser Seite
GraphQL starts with a schema - a typed contract, written in the Schema Definition Language (SDL), that
declares every type, every field, and every entry point into your graph. Both client and server share it: the
client knows exactly what it can ask for, the server knows exactly what it must resolve. Spring for GraphQL is
schema-first - you write the .graphqls file, and your Java code fulfils it.
The SDL: types and fields
A schema describes the shape of your data with object types and typed fields. Here's BookVault's catalog:
type Book {
id: ID! # ! means non-nullable
title: String!
isbn: String
availableCopies: Int!
author: Author! # a field can be another object type
}
type Author {
id: ID!
name: String!
books: [Book!]! # a list of Books
}Read the type modifiers carefully - they are the contract:
String!- a non-null String; the server promises it's never null.[Book!]!- a non-null list of non-null Books (the list exists and contains no null elements).author: Author!- the graph's edges: from aBookyou can traverse to itsAuthor, and from anAuthorback to itsbooks. This traversal is what lets one query gather related data.
Entry points: Query, Mutation, Subscription
Three special root types are the doors into the graph. Query is for reads:
type Query {
book(id: ID!): Book # fetch one book by id
books(topic: String): [Book!]! # list books, optionally filtered
}
type Mutation {
borrowBook(bookId: ID!, memberId: ID!): Loan # writes (later lesson)
}Every client query must start at a field of Query (or Mutation for writes). From that entry point, the
client traverses the graph via the object fields you declared. In Spring, you drop this file in
src/main/resources/graphql/schema.graphqls and Spring Boot's GraphQL starter picks it up automatically.
Schema-first vs. code-first
Spring for GraphQL is schema-first: the SDL file is the source of truth and your resolvers are validated against it at startup - a field with no data source is caught early. Some other stacks are code-first (annotations generate the schema). Schema-first keeps the contract human-readable and front-end-friendly, which is usually the point of adopting GraphQL in the first place.
Nullability is the contract
That ! is not decoration - it's a promise the engine enforces. If a non-null field (title: String!)
resolves to null at runtime, GraphQL doesn't silently return null; it errors that field and propagates the
null up to the nearest nullable parent. So nullability is a real design decision:
- Mark a field
!only when it genuinely always has a value. - Make fields that can be absent (an optional
isbn) nullable, or a single missing value can blank out a whole object.
The schema is the printed menu every diner and every cook shares. Object types are the dishes; fields are
the components listed under each dish; the edges (author: Author!) are the 'comes with' lines that let you
follow one dish to its side. The Query type is the 'you may order from this section' header - you can't
order something that isn't a starting point on the menu. And the ! is the kitchen's guarantee that a listed
component is always included - promise it on something that sometimes runs out, and one missing item spoils the
whole plate.
BookVault wants to add reviews. A Book should expose its list of reviews; each Review has a rating (1-5, always
present), an optional text comment, and the member who wrote it. Sketch the SDL Review type and the field you'd
add to Book. Which fields get ! and which don't?
In GraphQL SDL, what does the '!' in 'title: String!' mean?
Key takeaways
- GraphQL is schema-first in Spring: an SDL (.graphqls) file is the shared, typed contract between client and server.
- Object types have typed fields; fields that reference other types are the graph's edges that let one query traverse related data.
- Root types Query (reads), Mutation (writes), and Subscription (streams) are the only entry points; every query starts at one of their fields.
- The '!' marks non-nullable fields and is enforced - a non-null field resolving to null errors and propagates up, so nullability is a deliberate design choice.
- Spring Boot auto-loads schema.graphqls from resources/graphql and validates your resolvers against it at startup.