Komplett guide til Spring Boot 4 · leksjon

Skjemaførst-design og typetilordning

Definer et GraphQL-skjema og tilordne typer, spørringer og mutasjoner til Java-kontrollermetoder.

Leksjon 1 av 413 trinn

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, Float og Boolean er 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 → Java String
  • SDL Int → Java int / Integer
  • SDL ID → vanligvis String (eller Long med 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- og Mutation-typer.
  • @QueryMapping håndterer lesing, @MutationMapping hå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.

Gratis å komme i gang

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

  1. Skjemaførst-design og typetilordning
  2. Datahentere og binding av argumenter
  3. Løse N+1 med batchinnlastere
  4. Abonnementer, feil og skjemasikkerhet
← Tilbake til Komplett guide til Spring Boot 4