Spring Boot 4 – komplett guide · Lektion

Schema-first-design och typmappning

Definiera ett GraphQL-schema och mappa typer, queries och mutationer till Java-controller-metoder.

Lektion 1 av 413 steg

Schema-first-design och typmappning är en gratis lektion i Spring Boot 4 – komplett guide på CoddyKit. Detta är lektion 1 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Spring Boot 4 – komplett guide, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Spring Boot 4 – komplett guide innehåller totalt 4 lektioner.

Schema först i Spring för GraphQL

Spring for GraphQL är schema-first: Ni beskriver ert API i en fil med Schema Definition Language (SDL) för .graphql, och Er Java-kod mappas mot det.

  • schemat är den enda källan till sanning för API-kontraktet.
  • Klienter efterfrågar exakt de fält de behöver.
  • Era controllers tillhandahåller data för varje fält.

Enligt konventionen hittar Spring Boot automatiskt filer med ändelserna .graphqls / .graphql under src/main/resources/graphql/.

Definiera objekttyper i SDL

En GraphQL-objekttyp beskriver formen på en entitet. Varje fält har ett namn och en typ.

  • ID, String, Int, Float, Boolean är de inbyggda skalärtyperna.
  • Ett avslutande ! markerar ett fält som icke-null.
  • [Type] betecknar en lista.

Placera detta 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!]!
}

Rott typen för Query

Alla läsoperationer finns under den särskilda rot typen Query. Varje fält i Query är en startpunkt som en klient kan anropa.

  • Fält kan ta emot argument, till exempel bookById(id: ID!).
  • Returtypen kan vara ett enskilt objekt, en lista eller en skalär.

En nullbar returtyp (utan !) är lämplig när entiteten kanske inte finns.

type Query {
    bookById(id: ID!): Book
    allBooks: [Book!]!
    searchBooks(titleContains: String!): [Book!]!
}

Mappa en Query till en controller

Spring for GraphQL mappar schemafält till Java-metoder med hjälp av annoterade controllers. En klass som är annoterad med @Controller exponerar handler-metoder med @QueryMapping.

  • Metodnamnet måste matcha schemafältet, eller så anger Ni @QueryMapping("fieldName").
  • Argument binds med @Argument.

Detta är ramverkskod (den kräver Spring-runtime), så den kan inte köras fristå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();
    }
}

Typmappning: SDL till Java

Spring mappar GraphQL-typer till Java-typer efter fältnamn, inte efter arv. Er POJO (record eller klass) behöver bara ha matchande accessorer.

  • SDL String → Java String
  • SDL Int → Java int / Integer
  • SDL ID → vanligtvis String (eller Long efter typkonvertering)
  • SDL [Book!]! → List<Book>

Ett Java-record är den tydligaste representationen av en GraphQL-objekttyp.

public record Book(
    String id,
    String title,
    Integer pageCount,
    String authorId
) {}

public record Author(
    String id,
    String name
) {}

Detaljer om argumentbindning

Annoteringen @Argument binder ett namngivet schemaargument till en metodparameter.

  • Som standard måste parameternamnet matcha argumentnamnet (kompilering med -parameters krävs, vilket är aktiverat som standard i Spring Boot).
  • Åsidosätt detta explicit med @Argument("titleContains").
  • Komplexa input-typer binds automatiskt till ett Java-record eller en Java-klass.

Spring konverterar det inkommande GraphQL-värdet till parameterns Java-typ.

@QueryMapping
public List<Book> searchBooks(@Argument("titleContains") String fragment) {
    return books.findAll().stream()
        .filter(b -> b.title().toLowerCase().contains(fragment.toLowerCase()))
        .toList();
}

Lös kapslade fält med @SchemaMapping

När ett fält kräver mer arbete än en enkel getter (till exempel när Book.author måste slås upp) använder Ni @SchemaMapping. Källobjektet skickas in som en parameter.

  • Metodens klass/typ härleds från parametertypen, eller anges med @SchemaMapping(typeName = "Book").
  • Detta löser N+1-problemet genom att Ni senare kan batcha med @BatchMapping.

Här löser varje Book sitt author-fält vid behov.

@SchemaMapping
public Author author(Book book) {
    return authorRepository.findById(book.authorId())
        .orElseThrow(() -> new IllegalStateException("Author missing"));
}

Definiera mutationer i SDL

Skrivoperationer finns under rottypen Mutation. De tar vanligtvis emot ett input-objekt och returnerar den skapade eller uppdaterade entiteten.

  • Använd en särskild input-typ för argument — input-typer kan inte ha fält som refererar till objekttyper.
  • Genom att returnera den ändrade entiteten kan klienter hämta det aktuella tillståndet igen i en enda tur och retur.
input AddBookInput {
    title: String!
    pageCount: Int
    authorId: ID!
}

type Mutation {
    addBook(input: AddBookInput!): Book!
    deleteBook(id: ID!): Boolean!
}

Mappa en mutation till en controller

Mutationer mappas med @MutationMapping. En GraphQL-input-typ binds smidigt till ett Java-record via @Argument.

  • Record-fältnamnen måste matcha SDL-inputfältens namn.
  • Returnera entiteten för att uppfylla det icke-nullbara resultatet Book!.

Detta är fortfarande ramverkskod — den kräver Springs GraphQL-runtime och kan därför inte köras fristå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 typmappning i vanlig Java

Logiken som formar data bakom en resolver är vanlig Java — Ni kan resonera om den utan någon server. Nedan körs ett sökfilter (innehållet i searchBooks) som ett komplett fristående program.

  • Detta motsvarar exakt vad Er @QueryMapping-metod gör internt.
  • Ingen Spring, ingen schema-motor — bara typmappning och 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()));
    }
}

Där schema och kod möts

Vid uppstart validerar Spring att varje schemafält kan tillgodoses. Om ett fält saknar både getter och @SchemaMapping kan Ni få ett fel om olöst fält vid frågetillfället.

  • Egenskaper i Ert record löses automatiskt efter namn.
  • Beräknade / hämtade fält behöver en explicit mappningsmetod.
  • Använd gränssnittet GraphiQL (aktivera spring.graphql.graphiql.enabled=true) för att utforska det aktiva schemat.

Att hålla SDL- och Java-fältnamnen synkroniserade är den centrala disciplinen i schema-first-design.

Snabbkontroll

Ni har schemafältet Book.author: Author!, men ett Book-record lagrar bara authorId och saknar egenskapen author. Vad är det korrekta schema-first-sättet att lösa det?

Sammanfattning

Ni mappade ett GraphQL-schema till Spring-controllers enligt schema-first:

  • SDL-filer under src/main/resources/graphql/ definierar objekt-, input-, Query- och Mutation-typer.
  • @QueryMapping hanterar läsningar, @MutationMapping hanterar skrivningar, och båda binder argument med @Argument.
  • @SchemaMapping (och @BatchMapping) löser kapslade/beräknade fält från ett källobjekt.
  • Typer mappas efter fältnamn: records är den tydligaste representationen, och SDL:s skalärer mappas till sina naturliga Java-typer.

Håll SDL- och Java-namnen synkroniserade, så förblir schemat den enda källan till sanning.

Gratis att börja

Lär dig Java med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
21
Lektioner
84

Vanliga frågor

Är lektionen ”Schema-first-design och typmappning” gratis?

Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Spring Boot 4 – komplett guide, inklusive ”Schema-first-design och typmappning”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Spring Boot 4 – komplett guide innehåller totalt 4 lektioner.

Vad lär jag mig i ”Schema-first-design och typmappning”?

Definiera ett GraphQL-schema och mappa typer, queries och mutationer till Java-controller-metoder. Ni övar på Spring Boot 4 – komplett guide med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Spring Boot 4 – komplett guide?

Du behöver inga förkunskaper. Utbildningen i Spring Boot 4 – komplett guide på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 1 av 4.

Hur lång tid tar lektionen ”Schema-first-design och typmappning”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Spring Boot 4 – komplett guide-lektionen?

Ja. Varje Spring Boot 4 – komplett guide-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Schema-first-design och typmappning
  2. Data fetchers och argumentbindning
  3. Lös N+1 med batch loaders
  4. Prenumerationer, fel och schemasäkerhet
← Tillbaka till Spring Boot 4 – komplett guide