Lab 03

REST API und Fehlervertrag

REST-Schnittstellen mit stabilem Fehlervertrag, Problem Details und Tests entwerfen.

RESTProblem DetailsValidationTesting
SchwierigkeitMittel
Dauer45–75 Min
LernstufeStufe 6 – Praxislabor und Capstone
Hinweis: Die Lab-Kapitel sind standardmäßig geschlossen. Öffne nur den Abschnitt, den du gerade bearbeiten möchtest.

Lab-Bausteine

Die Seite ist als Arbeitsblatt aufgebaut: erst verstehen, dann Aufgabe bearbeiten, dann Lösungsskizze und Checkliste prüfen.

Lernziel

Du entwirfst eine REST-API, die Fehler nicht zufällig als Text zurückgibt, sondern einen stabilen, dokumentierten Fehlervertrag besitzt.

Ausgangslage

Ein Order-Service liefert bei Validierungsfehlern unterschiedliche JSON-Strukturen. Frontend, Tests und Support können Fehler dadurch nicht zuverlässig auswerten.

Aufgabe
  • Definiere ein einheitliches Problem-Details-Modell.
  • Mappe Domain-Fehler auf HTTP-Statuscodes.
  • Dokumentiere Beispielantworten.
  • Erstelle einen Test für einen typischen Fehlerfall.
Lösungsskizze
  • Domain-Fehler bleiben fachlich.
  • ControllerAdvice mappt technische HTTP-Antworten.
  • Fehlercodes sind stabil und maschinenlesbar.
  • Tests prüfen Status, Code und Struktur.
Typische Fehler
  • Stacktrace im API-Response.
  • HTTP 200 mit Fehlerobjekt.
  • Jeder Controller baut Fehlerantworten selbst.
  • Fehlercodes ändern sich ohne Versionierung.
Prüfcheckliste
  • Problem-Details-Struktur ist dokumentiert.
  • Mindestens ein Fehlerfall ist getestet.
  • Fachlicher Fehlercode ist stabil.
  • Kein interner Klassenname im Response.
Codebeispiel

Öffne diesen Abschnitt nur, wenn du die technische Umsetzung sehen möchtest. Der Codeblock ist farbig hervorgehoben und horizontal scrollbar.

ProblemDetails.javaJAVA
package com.acme.order.adapter.rest;

import java.time.Instant;
import java.util.Map;

public record ProblemDetails(
        String type,
        String title,
        int status,
        String detail,
        String errorCode,
        Instant timestamp,
        Map<String, Object> extensions
) {}
GlobalExceptionHandler.javaJAVA
package com.acme.order.adapter.rest;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.time.Instant;
import java.util.Map;

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(OrderAlreadyConfirmedException.class)
    ProblemDetails alreadyConfirmed(OrderAlreadyConfirmedException ex) {
        return new ProblemDetails(
            "https://errors.acme.local/order/already-confirmed",
            "Order already confirmed",
            HttpStatus.CONFLICT.value(),
            ex.getMessage(),
            "ORDER_ALREADY_CONFIRMED",
            Instant.now(),
            Map.of("retryable", false)
        );
    }
}
error-response.jsonJSON
{
  "type": "https://errors.acme.local/order/already-confirmed",
  "title": "Order already confirmed",
  "status": 409,
  "detail": "Order 4711 is already confirmed",
  "errorCode": "ORDER_ALREADY_CONFIRMED",
  "extensions": { "retryable": false }
}
Deep-Learning-Bezug

Dieses Lab gehört zu Stufe 6 – Praxislabor und Capstone. Die Stufe erklärt, warum das Lab in der Lernentwicklung genau an dieser Stelle steht.

⌂ Cockpit