Skjemaførst-design og typetilordning
Definer et GraphQL-skjema og tilordne typer, spørringer og mutasjoner til Java-kontrollermetoder.
Skjemaførst-design og typetilordning er en gratis leksjon i Komplett guide til Spring Boot 4 på CoddyKit. Dette er leksjon 1 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Komplett guide til Spring Boot 4, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Komplett guide til Spring Boot 4 inneholder totalt 4 leksjoner.
Skjemaførst i Spring for GraphQL
Spring for GraphQL er schema-first: De beskriver API-et i en .graphql-fil med Schema Definition Language (SDL), og Java-koden tilordnes dette.
- Skjemaet er den eneste sannhetskilden for API-kontrakten.
- Klienter ber om nøyaktig feltene de trenger.
- Kontrollerne Deres leverer dataene bak hvert felt.
Som standard finner Spring Boot automatisk .graphqls- og .graphql-filer under src/main/resources/graphql/.
Definere objekttyper i SDL
En GraphQL-objekttype beskriver strukturen til en entitet. Hvert felt har et navn og en type.
ID,String,Int,FloatogBooleaner de innebygde skalarene.- Et avsluttende
!markerer et felt som ikke-null. [Type]angir en liste.
Plasser dette i src/main/resources/graphql/schema.graphqls.
type Book {
id: ID!
title: String!
pageCount: Int
author: Author!
}
type Author {
id: ID!
name: String!
books: [Book!]!
}Rottypen Query
Alle leseoperasjoner ligger under den spesielle rot-typen Query. Hvert felt i Query er et inngangspunkt som en klient kan kalle.
- Felt kan ta imot argumenter, for eksempel
bookById(id: ID!). - Returtypen kan være ett enkelt objekt, en liste eller en skalar.
En nullable returtype (uten !) passer når entiteten kanskje ikke finnes.
type Query {
bookById(id: ID!): Book
allBooks: [Book!]!
searchBooks(titleContains: String!): [Book!]!
}Koble en Query til en kontroller
Spring for GraphQL kobler skjemafelt til Java-metoder ved hjelp av annoterte kontrollere. En klasse annotert med @Controller eksponerer behandlingsmetoder med @QueryMapping.
- Metodenavnet må samsvare med skjemafeltet, eller De kan angi
@QueryMapping("fieldName"). - Argumenter bindes med
@Argument.
Dette er rammeverkskode (den trenger Spring-kjøretidsmiljøet), så den kan ikke kjøres frittstående.
@Controller
public class BookController {
private final BookRepository books;
public BookController(BookRepository books) {
this.books = books;
}
@QueryMapping
public Book bookById(@Argument String id) {
return books.findById(id).orElse(null);
}
@QueryMapping
public List<Book> allBooks() {
return books.findAll();
}
}Typetilordning: SDL til Java
Spring tilordner GraphQL-typer til Java-typer etter feltnavn, ikke etter arv. POJO-en Deres (record eller klasse) trenger bare samsvarende tilgangsmetoder.
- SDL
String→ JavaString - SDL
Int→ Javaint/Integer - SDL
ID→ vanligvisString(ellerLongmed typekonvertering) - SDL
[Book!]!→List<Book>
En Java-record er den ryddigste representasjonen av en GraphQL-objekttype.
public record Book(
String id,
String title,
Integer pageCount,
String authorId
) {}
public record Author(
String id,
String name
) {}Detaljer om argumentbinding
Annotasjonen @Argument binder et navngitt skjemargument til en metodeparameter.
- Som standard må parameternavnet samsvare med argumentnavnet (krever kompilering med
-parameters, som er aktivert som standard i Spring Boot). - Overstyr dette eksplisitt med
@Argument("titleContains"). - Komplekse input-typer bindes automatisk til en Java-record eller -klasse.
Spring konverterer den innkommende GraphQL-verdien til Java-typen til parameteren Deres.
@QueryMapping
public List<Book> searchBooks(@Argument("titleContains") String fragment) {
return books.findAll().stream()
.filter(b -> b.title().toLowerCase().contains(fragment.toLowerCase()))
.toList();
}Løse nestede felt med @SchemaMapping
Når et felt trenger mer arbeid enn en enkel getter (for eksempel når Book.author må slås opp), bruker De @SchemaMapping. Kildeobjektet sendes inn som en parameter.
- Metodens klasse/type utledes fra parametertypen, eller angis med
@SchemaMapping(typeName = "Book"). - Dette løser N+1-problemet ved at De senere kan samle oppslagene med
@BatchMapping.
Her løser hver Book feltet author ved behov.
@SchemaMapping
public Author author(Book book) {
return authorRepository.findById(book.authorId())
.orElseThrow(() -> new IllegalStateException("Author missing"));
}Definere mutasjoner i SDL
Skriveoperasjoner ligger under rot-typen Mutation. De tar vanligvis imot et input-objekt og returnerer den opprettede eller oppdaterte entiteten.
- Bruk en dedikert
input-type for argumenter — input-typer kan ikke ha felt som refererer til objekttyper. - Ved å returnere den muterte entiteten kan klienter hente oppdatert tilstand på nytt i én rundtur.
input AddBookInput {
title: String!
pageCount: Int
authorId: ID!
}
type Mutation {
addBook(input: AddBookInput!): Book!
deleteBook(id: ID!): Boolean!
}Koble en mutasjon til en kontroller
Mutasjoner kobles med @MutationMapping. En GraphQL-input-type bindes enkelt til en Java-record via @Argument.
- Feltnavnene i record-en må samsvare med feltnavnene i SDL-inputen.
- Returner entiteten for å oppfylle det ikke-nullbare
Book!-resultatet.
Dette er fortsatt rammeverkskode — den trenger Spring sitt GraphQL-kjøretidsmiljø og kan derfor ikke kjøres frittstående.
public record AddBookInput(String title, Integer pageCount, String authorId) {}
@MutationMapping
public Book addBook(@Argument AddBookInput input) {
Book created = new Book(
UUID.randomUUID().toString(),
input.title(),
input.pageCount(),
input.authorId()
);
return books.save(created);
}Ren typetilordning i vanlig Java
Datalogikken bak en resolver er vanlig Java — De kan forstå den uten en server. Nedenfor kjøres et søkefilter (innholdet i searchBooks) som et komplett frittstående program.
- Dette gjenspeiler nøyaktig det
@QueryMapping-metoden Deres gjør internt. - Ingen Spring, ingen skjemamotor — bare typetilordning og filtrering.
import java.util.List;
public class Main {
record Book(String id, String title, Integer pageCount) {}
static List<Book> searchBooks(List<Book> all, String fragment) {
return all.stream()
.filter(b -> b.title().toLowerCase().contains(fragment.toLowerCase()))
.toList();
}
public static void main(String[] args) {
List<Book> catalog = List.of(
new Book("1", "Spring in Action", 600),
new Book("2", "GraphQL Basics", 220),
new Book("3", "Effective Java", 412)
);
searchBooks(catalog, "graphql").forEach(b -> System.out.println(b.title()));
}
}Der skjema og kode møtes
Ved oppstart validerer Spring at hvert skjemafelt kan løses. Hvis et felt verken har en getter eller en @SchemaMapping, kan De få en feil om uløst felt ved spørringstidspunktet.
- Egenskaper i record-en løses automatisk etter navn.
- Beregnede / hentede felt trenger en eksplisitt tilordningsmetode.
- Bruk GraphiQL-grensesnittet (aktiver
spring.graphql.graphiql.enabled=true) for å utforske det aktive skjemaet.
Å holde SDL- og Java-feltnavn samordnet er den grunnleggende disiplinen i schema-first-design.
Hurtigsjekk
De har skjemafeltet Book.author: Author!, men en Book-record lagrer bare authorId og har ingen author-egenskap. Hva er den riktige schema-first-måten å løse dette på?
Oppsummering
De har koblet et GraphQL-skjema til Spring-kontrollere med schema-first:
- SDL-filer under
src/main/resources/graphql/definerer objekt-,input-,Query- ogMutation-typer. @QueryMappinghåndterer lesing,@MutationMappinghåndterer skriving, og begge binder argumenter med@Argument.@SchemaMapping(og@BatchMapping) løser nestede/beregnede felt fra et kildeobjekt.- Typer tilordnes etter feltnavn: records er den ryddigste representasjonen, og SDL-skalarer tilordnes til sine naturlige Java-typer.
Hold SDL- og Javanavn samordnet, så forblir skjemaet den eneste sannhetskilden.
Lær deg Java med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 21
- Leksjoner
- 84
Ofte stilte spørsmål
Er leksjonen «Skjemaførst-design og typetilordning» gratis?
Ja – du kan lese valgfritt 3 av leksjonene i læringsstien Komplett guide til Spring Boot 4, inkludert «Skjemaførst-design og typetilordning», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i Komplett guide til Spring Boot 4 inneholder totalt 4 leksjoner.
Hva lærer jeg i «Skjemaførst-design og typetilordning»?
Definer et GraphQL-skjema og tilordne typer, spørringer og mutasjoner til Java-kontrollermetoder. Du øver på Komplett guide til Spring Boot 4 med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med Komplett guide til Spring Boot 4?
Ingen tidligere erfaring er nødvendig. Komplett guide til Spring Boot 4 på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 1 av 4.
Hvor lang tid tar leksjonen «Skjemaførst-design og typetilordning»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne Komplett guide til Spring Boot 4-leksjonen?
Ja. Alle Komplett guide til Spring Boot 4-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Skjemaførst-design og typetilordning
- Datahentere og binding av argumenter
- Løse N+1 med batchinnlastere
- Abonnementer, feil og skjemasikkerhet