Vom Auftrag zur API: Anforderungen und OpenAPI-Vertrag für das Mitfahrlabor-Backend

https://bildung.social/@oerinformatik/

https://oer-informatik.de/spring-boot-anforderungen-api-entwurf

OpenAPI, API-Entwurf, User Story, Abnahmekriterien, V-Modell, REST-API, Anwendungsfalldiagramm, Zustandsdiagramm, Schichtenarchitektur, Spring Boot

tl/dr; (ca. 21 min Lesezeit): Bevor die erste Zeile Java entsteht, wird geplant: Aus dem Auftrag werden User Stories mit Abnahmekriterien, aus den Fachregeln ein Fachmodell mit Zustandsdiagramm, aus der Architektur ein Schichtenmodell und aus allem zusammen ein API-Vertrag im Format OpenAPI. Damit ist die linke Seite des V-Modells für das Mitfahrlabor-Backend vollständig, und jede spätere Testebene weiß, wogegen sie prüft [AI-Assisted]. (Zuletzt geändert am 11.11.2026)

Dieser Artikel ist Teil einer Artikelreihe über ein REST-Backend mit Spring Boot: Überblick und Fahrplan / 01 Anforderungen und API-Vertrag / Übungsaufgaben zu 01

Schon fit in diesem Thema? Nutze die Kann-Liste und die Leitfragen unter dem Artikel als Checkliste, ob Du die relevanten Kompetenzen bereits hast.

Dieser Artikel baut auf der Kann-Liste der Artikel Representational State Transfer (REST) und Das V-Modell auf.

Als API-Entwurfs-Grundlagen kann ich nach Durchlesen des Artikels…

  • … eine Anforderung als User Story notieren und dazu überprüfbare Abnahmekriterien in der Form Angenommen – Wenn – Dann formulieren.

  • … Fachregeln von formalen Eingaberegeln unterscheiden und begründen, wo im System sie geprüft werden.

  • … die Zustände einer Buchung und die erlaubten Übergänge in einem Zustandsdiagramm darstellen.

  • … die Schichten Controller, Service, Repository und Domäne mit ihren Abhängigkeiten erklären.

  • … für Ressourcen passende URIs, HTTP-Methoden und Statuscodes festlegen und dabei 400, 404, 409 und 422 unterscheiden.

  • … den Aufbau einer OpenAPI-Datei (info, servers, paths, components) erklären und einen Endpunkt mit Schema darin notieren.

Darüber hinaus kann ich als API-Entwurfs-Expertenwissen…

  • … beurteilen, warum ein Angebot per PATCH abgesagt und nicht per DELETE gelöscht wird.

  • … jedem Entwurfsdokument die Testebene zuordnen, die es später prüft, und daraus ableiten, was ein Test als Grundlage braucht.

Wer sofort programmiert, programmiert oft am Bedarf vorbei. Im V-Modell steht deshalb vor der Implementierung der linke Ast: Anforderungen, Systementwurf, Architekturentwurf und Modulentwurf. Für unser kleines Backend schaffen wir alle vier Stufen in einem Artikel. Das Ergebnis sind keine dicken Dokumente, sondern ein paar knappe Festlegungen, auf die sich alle folgenden Artikel stützen: Die Tests in den Artikeln 04 bis 11 prüfen genau gegen das, was hier steht.

Fahrplan der Artikelreihe im V-Modell, hervorgehoben sind die vier Entwurfsstufen aus Artikel 01: Anforderungen, Systementwurf, Architekturentwurf und Modulentwurf (mit KI erstellt)

Der Auftrag: Fahrgemeinschaften für den Schulweg

Am erfundenen DBH-Berufskolleg pendeln viele Auszubildende an ein bis zwei Tagen pro Woche aus dem Umland. Bus und Bahn fahren morgens ungünstig, einige kommen mit dem Auto. Die Schülervertretung regt deshalb Fahrgemeinschaften an, und Thomas Becker, Verbindungslehrer und Projektleiter, beauftragt das Projektteam der Schule mit der App Mitfahrlabor. Seine Vorgabe: eine sichere, einfache Lösung, die ohne viel Betreuung läuft.

Für den Start soll nicht alles auf einmal kommen. Das Team einigt sich auf ein MVP (Minimum Viable Product): Fahrten anbieten, suchen und anfragen, Anfragen bestätigen und die Anzeige auf den Flurmonitoren. Gesuche, Bewertungen, Fahrzeuge, Erinnerungen und die Anmeldung mit dem Schulkonto kommen später. Das Anwendungsfalldiagramm zeigt, wer welche Funktion nutzt:

UML-Anwendungsfalldiagramm des MVP: Die abstrakte Rolle Nutzende sieht Haltepunkte an, Fahrer*innen bieten Fahrten an, ändern oder sagen sie ab und bestätigen oder lehnen Anfragen ab, Mitfahrende suchen Fahrten, fragen Plätze an und stornieren Buchungen, der Flurmonitor zeigt offene Angebote anonym an (mit KI erstellt)

Fahrer*innen und Mitfahrende sind beide Nutzende. Weil beide die Haltepunkte ansehen dürfen, hängt dieser Anwendungsfall an der abstrakten Rolle „Nutzende“. Der Flurmonitor ist kein Mensch, sondern ein Gerät im Flur. Er ist trotzdem ein Akteur, weil er von außen auf das System zugreift.

Anforderungen: User Stories mit Abnahmekriterien

Jeder Anwendungsfall wird zu einer User Story. Sie beschreibt eine Anforderung aus Sicht der Nutzenden in einem Satz mit drei Teilen: Wer will etwas? Was will die Person? Wozu?

Als Fahrer*in möchte ich eine Fahrt anbieten, damit andere mitfahren und wir die Kosten teilen.

Ein solcher Satz reicht nicht, um später zu entscheiden, ob die Software fertig ist. Deshalb bekommt jede Story Abnahmekriterien. Wir notieren sie in der Form Angenommen – Wenn – Dann (englisch Given – When – Then): Angenommen beschreibt die Ausgangslage, Wenn die Aktion, Dann das erwartete Ergebnis. So wird jedes Kriterium zu einem Testfall, den jemand ohne Kenntnis des Codes durchführen kann.

User Stories des MVP mit einer Auswahl der Abnahmekriterien
ID User Story Abnahmekriterien (Auswahl)
US-01 Als Nutzende*r möchte ich alle Haltepunkte sehen, damit ich einen Treffpunkt auswählen kann. alle Haltepunkte mit Name, Ort, Entfernung; unbekannte ID → „nicht gefunden“
US-02 Als Fahrer*in möchte ich eine Fahrt anbieten, damit andere mitfahren und wir die Kosten teilen. Angebot ist danach „offen“; zu hoher Kostenbeitrag, fehlender Führerschein, Datum in der Vergangenheit → abgelehnt
US-03 Als Fahrer*in möchte ich mein Angebot ändern oder absagen, damit Mitfahrende aktuelle Angaben sehen. abgesagtes Angebot bleibt abrufbar; ein abgesagtes Angebot lässt sich nicht mehr ändern
US-04 Als Mitfahrende*r möchte ich offene Fahrten nach Datum, Richtung und Haltepunkt suchen. nur offene Angebote; leere Liste, wenn nichts passt
US-05 Als Mitfahrende*r möchte ich einen Platz anfragen, damit ich mitfahren kann. Buchung „angefragt“; minderjährig ohne Einwilligung, eigene Fahrt, volles Angebot, doppelte Anfrage → abgelehnt
US-06 Als Fahrer*in möchte ich Anfragen bestätigen oder ablehnen, damit ich entscheide, wer mitfährt. bestätigen senkt die freien Plätze, bei 0 ist das Angebot „voll“
US-07 Als Mitfahrende*r möchte ich meine Buchung stornieren, damit der Platz für andere frei wird. bestätigte Buchung stornieren gibt den Platz zurück
US-08 Als Flurmonitor möchte ich offene Angebote anzeigen, damit Auszubildende Fahrten entdecken. keine Namen, keine Pseudonyme; nur künftige, offene Angebote

Ausführlich sieht das zum Beispiel für US-02 so aus:

  • AK-02.1: Angenommen, Ben Richter (Nutzer 1) hat einen Führerschein. Wenn er für den Haltepunkt Gütersloh eine Fahrt zur Schule am nächsten Schultag um 07:00 Uhr mit 2 Plätzen und 1,80 Euro anbietet, dann ist das Angebot gespeichert und hat den Status „offen“.

  • AK-02.2: Angenommen, der Haltepunkt Gütersloh ist 18,6 km entfernt. Wenn der Kostenbeitrag 1,90 Euro beträgt, dann wird das Angebot abgelehnt, weil höchstens 1,86 Euro erlaubt sind.

Alle Stories mit allen Abnahmekriterien und den Testdaten stehen in der Datei user-stories.md. Der Abnahmetest in Artikel 11 arbeitet sie Punkt für Punkt ab.

Modulentwurf: Fachmodell und Fachregeln

Aus den Stories lassen sich die Dinge ablesen, mit denen das System arbeitet: Haltepunkte, Nutzende, Angebote und Buchungen. Das Klassendiagramm zeigt sie mit ihren Attributen und Beziehungen. Es ist ein Fachmodell: Es beschreibt die Welt des Mitfahrlabors, nicht Tabellen oder Java-Klassen. Typen wie Datum oder Uhrzeit werden erst bei der Umsetzung zu LocalDate und LocalTime.

UML-Klassendiagramm des Fachmodells: Ein Nutzer bietet als Fahrer beliebig viele Angebote an, jedes Angebot hat genau einen Haltepunkt als Treffpunkt und erhält beliebig viele Buchungen, jede Buchung gehört zu genau einem Nutzer als Mitfahrer; dazu die Aufzählungen Richtung, AngebotStatus und BuchungStatus (mit KI erstellt)

Spannender als die Attribute sind die Regeln, die sie verbinden. Aus dem Szenario und den Gesprächen mit der Projektleitung ergeben sich sechs Fachregeln:

  1. Kostenbeitrag: Je Person höchstens 0,10 Euro je Kilometer Entfernung des Haltepunkts. Für Gütersloh (18,6 km) sind das 18{,}6 \cdot 0{,}10\,\mathrm{€} = 1{,}86\,\mathrm{€}. Gewinn ist ausgeschlossen.

  2. Führerschein: Nur wer einen Führerschein hat, darf Fahrten anbieten.

  3. Einwilligung: Wer am Tag der Fahrt noch nicht 18 Jahre alt ist, braucht die Einwilligung der Erziehungsberechtigten.

  4. Plätze: Ein Angebot hat 1 bis 8 freie Plätze. Ist kein Platz mehr frei, ist das Angebot „voll“.

  5. Buchungen: Niemand bucht die eigene Fahrt, und je Angebot hat jede Person höchstens eine Buchung.

  6. Status: Eine Buchung durchläuft nur die erlaubten Zustandswechsel (siehe Zustandsdiagramm).

Die letzte Regel lässt sich am besten zeichnen. Eine Buchung beginnt immer als „angefragt“. Die Fahrerin oder der Fahrer bestätigt sie, solange noch ein Platz frei ist, oder lehnt sie ab. Stornieren kann die mitfahrende Person sowohl eine angefragte als auch eine bestätigte Buchung. Nur im zweiten Fall wird ein Platz frei. „abgelehnt“ und „storniert“ sind Endzustände.

UML-Zustandsdiagramm einer Buchung: vom Start nach angefragt; von angefragt mit bestaetigen() und Wächter freiePlaetze > 0 nach bestätigt mit dem Effekt freiePlaetzeVerringern(), mit ablehnen() nach abgelehnt, mit stornieren() nach storniert; von bestätigt mit stornieren() nach storniert mit dem Effekt freiePlaetzeErhoehen(); abgelehnt und storniert enden (mit KI erstellt)

Auch ein Angebot hat einen Status: „offen“, „voll“, „abgesagt“ und „durchgeführt“. Es wechselt zwischen „offen“ und „voll“, je nachdem, ob Plätze frei sind, und kann von beiden Zuständen aus abgesagt werden. „durchgeführt“ setzt später ein nächtlicher Lauf; im MVP spielt er noch keine Rolle.

Nicht jede Regel kann man an der Anfrage allein erkennen. Ob ein Feld fehlt oder die Platzzahl zwischen 1 und 8 liegt, sieht man der Anfrage an; das kann schon der API-Vertrag festlegen. Ob der Kostenbeitrag zu hoch ist, weiß das Backend erst, wenn es die Entfernung des Haltepunkts aus der Datenbank geholt hat. Diese Unterscheidung bestimmt, wo eine Regel geprüft wird:

Wo die Regeln des Mitfahrlabors geprüft werden
Regel an der Anfrage erkennbar? geprüft durch
Pflichtfelder, Platzzahl 1 bis 8, Uhrzeit im Format HH:MM ja API-Vertrag (Bean Validation, Artikel 03)
Kostenbeitrag je Kilometer nein, braucht die Entfernung des Haltepunkts Fachlogik (Artikel 04)
Führerschein, Einwilligung, eigene Fahrt nein, braucht die Daten der Person Service (Artikel 08)
erlaubte Statuswechsel, freie Plätze nein, braucht den aktuellen Zustand Fachlogik und Service (Artikel 04, 08)

Architekturentwurf: Schichten mit klaren Abhängigkeiten

Das Backend wird in Schichten gegliedert. Jede Schicht hat eine Aufgabe und darf nur die Schichten unter sich benutzen. Im Code wird jede Schicht zu einem Java-Paket:

UML-Paketdiagramm der Schichten im Paket de.dbh.mitfahrlabor: web nutzt api und service, service nutzt repository und domain, repository nutzt domain; das Paket api mit dem Unterpaket model wird aus openapi.yaml erzeugt (mit KI erstellt)
  • web enthält die Controller. Sie nehmen HTTP-Anfragen an, rufen den Service auf und übersetzen das Ergebnis in eine Antwort mit Statuscode.

  • api enthält Schnittstellen und Datenklassen für Anfragen und Antworten. Diese schreibt niemand von Hand: Sie werden in Artikel 03 aus dem API-Vertrag erzeugt. Die Controller implementieren diese Schnittstellen.

  • service enthält die Abläufe der Anwendungsfälle: Angebot anlegen, Platz anfragen, Buchung bestätigen. Hier werden die Fachregeln angewendet.

  • repository speichert und lädt Daten. Mit Spring Data JPA genügen dafür Interfaces.

  • domain enthält die Klassen des Fachmodells mit ihren Regeln. Sie hängt von keiner anderen Schicht ab und lässt sich deshalb ohne Datenbank und ohne Server testen.

Diese Gliederung zahlt sich beim Testen aus: Fachlogik in domain prüfen Komponententests in Millisekunden, das Zusammenspiel von repository und Datenbank prüft ein Integrationstest, und die Web-Schicht testen wir, ohne dass eine Datenbank läuft.

Systementwurf: die REST-Ressourcen

Von außen sieht man das Backend nur über seine Schnittstelle. Welche HTTP-Methoden es gibt und welche Garantien sie geben, beschreibt der Artikel REST-Grundlagen. Hier wenden wir das an. Alle Pfade beginnen mit der Versionsnummer /v1, damit eine spätere, inkompatible Fassung der API parallel laufen kann.

Endpunkte der Mitfahrlabor-API (Version 1)
Methode Pfad Zweck Story Erfolg Fehler
GET /haltepunkte alle Haltepunkte US-01 200 –
GET /haltepunkte/{haltepunktId} ein Haltepunkt US-01 200 404
GET /angebote?datum=…&richtung=…&haltepunkt=… offene Angebote suchen US-04 200 400
POST /angebote Fahrt anbieten US-02 201 400, 404, 422
GET /angebote/{angebotId} ein Angebot US-03 200 404
PATCH /angebote/{angebotId} Angebot ändern oder absagen US-03 200 400, 404, 409, 422
GET /angebote/{angebotId}/buchungen Buchungen eines Angebots US-06 200 404
POST /angebote/{angebotId}/buchungen Platz anfragen US-05 201 400, 404, 409, 422
GET /buchungen/{buchungId} eine Buchung US-07 200 404
PATCH /buchungen/{buchungId} bestätigen, ablehnen, stornieren US-06, US-07 200 400, 404, 409
GET /monitor/eintraege?haltepunkt=…&richtung=…&datum=…&max=… anonyme Einträge für die Flurmonitore US-08 200 400

Einige Entscheidungen verdienen eine Begründung:

  • Ressourcen im Plural, ohne Verben: /angebote ist die Sammlung, /angebote/7 ein Element davon. Was passiert, sagt die Methode, nicht der Pfad (also kein /angebote/anlegen).

  • Buchungen unter dem Angebot anlegen: Eine Anfrage gehört immer zu einem Angebot, deshalb POST /angebote/7/buchungen. Danach hat die Buchung eine eigene Adresse /buchungen/12, über die sie bestätigt oder storniert wird.

  • Absagen ist ein Statuswechsel, kein Löschen: Mit DELETE wäre das Angebot verschwunden, und wer schon gebucht hat, sähe nur „nicht gefunden“. Deshalb setzt PATCH den Status auf abgesagt, und das Angebot bleibt abrufbar.

  • Ein eigener Pfad für den Monitor: /monitor/eintraege liefert nur, was auf einem Flurbildschirm stehen darf. So kann kein Monitor versehentlich Namen anzeigen, auch wenn das Angebot selbst mehr Daten hat.

  • Wer handelt, steht vorerst im Body: Solange es keine Anmeldung gibt, nennt die Anfrage die Nutzer-ID selbst (fahrerId, mitfahrerId). Dass das jeder fälschen kann, ist der Anlass für den Change Request in Artikel 12.

Bei den Fehlercodes unterscheiden wir vier Fälle, damit ein Frontend gezielt reagieren kann:

Fehlercodes der Mitfahrlabor-API
Code Bedeutung Beispiel
400 Bad Request Die Anfrage passt nicht zum Vertrag. Pflichtfeld datum fehlt, freiePlaetze ist 12
404 Not Found Die Ressource gibt es nicht. GET /angebote/999, Haltepunkt 99 im neuen Angebot
409 Conflict Die Änderung passt nicht zum aktuellen Zustand. Platz anfragen bei einem vollen Angebot, stornierte Buchung bestätigen
422 Unprocessable Content Die Anfrage ist formal richtig, verletzt aber eine Fachregel. Kostenbeitrag zu hoch, Einwilligung fehlt, eigene Fahrt anfragen

Die Antwort im Fehlerfall ist immer gleich aufgebaut, und zwar nach dem Standard Problem Details for HTTP APIs (RFC 9457). Spring Boot unterstützt dieses Format; in Artikel 09 nutzen wir es.

Der API-Vertrag mit OpenAPI

Die Tabelle oben ist für Menschen gedacht. Damit Werkzeuge damit arbeiten können, beschreiben wir dieselbe Schnittstelle maschinenlesbar im Format OpenAPI (früher Swagger). Die Datei heißt openapi.yaml und ist unser API-Vertrag: Das Backend verspricht, genau so zu antworten, und die Frontends verlassen sich darauf. Weil der Vertrag vor dem Code entsteht, spricht man von Contract First oder API First.

Die aktuellen Fassungen der Spezifikation sind OpenAPI 3.1 und 3.2. Wir verwenden bewusst OpenAPI 3.0.3: Der Codegenerator, mit dem wir in Artikel 03 Java-Code aus dem Vertrag erzeugen, unterstützt 3.0 vollständig, 3.1 dagegen nur als Beta. Für unsere Zwecke unterscheiden sich die Fassungen kaum.

Eine OpenAPI-Datei hat vier Hauptteile:

  • info nennt Titel, Version und eine Beschreibung der API.

  • servers gibt an, unter welcher Adresse die API erreichbar ist, bei uns http://localhost:8080/v1.

  • paths beschreibt jeden Endpunkt: Pfad, Methode, Parameter, Body und alle möglichen Antworten.

  • components sammelt wiederverwendbare Teile: Schemas für die Daten, Parameter und Antworten. An anderen Stellen verweist $ref darauf.

So sieht der Endpunkt „Fahrt anbieten“ aus (gekürzt um das Beispiel für den Body):

paths:
  /angebote:
    post:
      tags: [angebote]
      operationId: legeAngebotAn
      summary: eine Fahrt anbieten
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AngebotNeu'
      responses:
        '201':
          description: Angebot angelegt
          headers:
            Location:
              description: URI des neuen Angebots
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Angebot'
        '400':
          $ref: '#/components/responses/UngueltigeAnfrage'
        '404':
          $ref: '#/components/responses/NichtGefunden'
        '422':
          $ref: '#/components/responses/FachregelVerletzt'

Die operationId wird später zum Namen der Java-Methode, das tag zum Namen der Schnittstelle (AngeboteApi). Was im Body stehen muss, legt das Schema AngebotNeu fest:

components:
  schemas:
    AngebotNeu:
      type: object
      required: [fahrerId, haltepunktId, richtung, datum, abfahrt, freiePlaetze, kostenbeitragEur]
      properties:
        fahrerId:
          type: integer
          format: int64
        haltepunktId:
          type: integer
          format: int64
        richtung:
          $ref: '#/components/schemas/Richtung'
        datum:
          type: string
          format: date
        abfahrt:
          type: string
          pattern: '^([01][0-9]|2[0-3]):[0-5][0-9]$'
          description: Uhrzeit im Format HH:MM
        freiePlaetze:
          type: integer
          minimum: 1
          maximum: 8
        kostenbeitragEur:
          type: number
          format: double
          minimum: 0
          description: je Person; höchstens 0,10 Euro je km (Fachregel, prüft das Backend)
    Richtung:
      type: string
      enum: [zur-schule, nach-hause]

Hier stecken die formalen Regeln aus der Tabelle des Modulentwurfs: required für die Pflichtfelder, minimum und maximum für die Platzzahl, pattern für die Uhrzeit, enum für die erlaubten Werte der Richtung. In JSON stehen die Werte klein und mit Bindestrich (zur-schule), damit sie auch in einer URL funktionieren; in Java werden daraus später die Konstanten ZUR_SCHULE und NACH_HAUSE. Die Grenze von 0,10 Euro je Kilometer steht nur als Beschreibung im Vertrag, prüfen kann sie erst das Backend.

Damit die Fehlerantworten nicht bei jedem Endpunkt neu beschrieben werden müssen, liegen sie unter components/responses. Ein Beispiel einer Antwort mit Status 422 ist gleich mit angegeben:

components:
  responses:
    FachregelVerletzt:
      description: Die Anfrage ist formal richtig, verletzt aber eine Fachregel.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://mitfahrlabor.example/probleme/kostenbeitrag-zu-hoch
            title: Kostenbeitrag zu hoch
            status: 422
            detail: Für den Haltepunkt Gütersloh (18,6 km) sind höchstens 1,86 Euro je Person erlaubt.
            instance: /v1/angebote

Den vollständigen Vertrag mit allen elf Operationen kannst Du als openapi.yaml herunterladen.

Den Vertrag ansehen und prüfen

Eine YAML-Datei mit rund 500 Zeilen liest niemand gern am Stück. Editoren für OpenAPI zeigen daneben eine Vorschau mit allen Endpunkten, Schemas und Beispielen und markieren Fehler sofort:

  • der Swagger Editor im Browser: Datei hineinkopieren, links bearbeiten, rechts die Vorschau ansehen,

  • Erweiterungen für VS Code oder IntelliJ IDEA, die OpenAPI-Dateien prüfen und eine Vorschau anzeigen.

Achte beim Durchsehen vor allem auf drei Dinge: Hat jede Operation eine eindeutige operationId? Ist zu jedem Fehlerfall aus den User Stories eine Antwort beschrieben? Stimmen Pflichtfelder und Grenzen mit den Fachregeln überein? Ab Artikel 03 prüft der Build den Vertrag bei jedem Lauf automatisch; ein fehlerhafter Vertrag lässt dann den Build scheitern.

Fazit: Was jetzt feststeht

Mit diesem Artikel ist der linke Ast des V-Modells fertig. Jedes Ergebnis hat auf dem rechten Ast eine Testebene, die es später prüft:

Ergebnisse des linken Asts und die Testebenen, die sie prüfen
Entwurfsstufe Ergebnis geprüft durch
Anforderungen User Stories mit Abnahmekriterien (user-stories.md) Abnahmetest, Artikel 11
Systementwurf API-Vertrag openapi.yaml, Tabelle der Endpunkte Systemtest, Artikel 11
Architekturentwurf Schichten und Pakete Integrationstests, Artikel 07 und 10
Modulentwurf Fachmodell, Fachregeln, Zustandsdiagramm Komponententests, Artikel 04 und 08

Nächster Artikel

Im nächsten Artikel legst Du das Spring-Boot-Projekt an und baust den ersten Endpunkt GET /haltepunkte von Hand, damit Du siehst, was der Codegenerator später für Dich erledigt.

Leitfragen

  1. Aus welchen drei Teilen besteht eine User Story, und wozu braucht sie Abnahmekriterien?

Eine User Story nennt die Rolle, das Ziel und den Nutzen („Als … möchte ich …, damit …“). Abnahmekriterien in der Form Angenommen – Wenn – Dann machen sie überprüfbar: Jedes Kriterium ist ein Testfall, mit dem man entscheidet, ob die Anforderung erfüllt ist. siehe Abschnitt „Anforderungen: User Stories mit Abnahmekriterien“

  1. Warum kann der API-Vertrag die Regel „höchstens 0,10 Euro je Kilometer“ nicht selbst prüfen?

Der erlaubte Höchstbetrag hängt von der Entfernung des Haltepunkts ab, die nicht in der Anfrage steht, sondern in der Datenbank. Der Vertrag prüft nur, was man der Anfrage allein ansieht (Pflichtfelder, Grenzen, Formate); die Fachregel prüft das Backend. siehe Abschnitt „Modulentwurf: Fachmodell und Fachregeln“

  1. In welchen Fällen kann eine Buchung storniert werden, und wann wird dabei ein Platz frei?

Stornieren ist aus den Zuständen „angefragt“ und „bestätigt“ möglich. Nur beim Stornieren einer bestätigten Buchung wird ein Platz frei, weil nur dann vorher ein Platz belegt war. siehe Abschnitt „Modulentwurf: Fachmodell und Fachregeln“

  1. Warum hängt das Paket domain von keiner anderen Schicht ab?

Die Fachklassen und ihre Regeln sollen ohne Datenbank, Server oder Framework funktionieren. Dadurch lassen sie sich schnell in Komponententests prüfen, und Änderungen an Web- oder Datenbankschicht berühren sie nicht. siehe Abschnitt „Architekturentwurf: Schichten mit klaren Abhängigkeiten“

  1. Warum wird ein Angebot mit PATCH abgesagt und nicht mit DELETE gelöscht?

Absagen ändert nur den Status. Mit DELETE wäre das Angebot verschwunden, und Mitfahrende, die schon gebucht haben, erhielten nur „nicht gefunden“ statt des Hinweises „abgesagt“. siehe Abschnitt „Systementwurf: die REST-Ressourcen“

  1. Worin unterscheiden sich die Statuscodes 400, 409 und 422 in der Mitfahrlabor-API?

400 bedeutet, dass die Anfrage nicht zum Vertrag passt (z. B. Pflichtfeld fehlt). 409 bedeutet, dass sie nicht zum aktuellen Zustand passt (z. B. Angebot voll). 422 bedeutet, dass sie formal richtig ist, aber eine Fachregel verletzt (z. B. Kostenbeitrag zu hoch). siehe Abschnitt „Systementwurf: die REST-Ressourcen“

  1. Welche Aufgaben haben die Teile paths und components in einer OpenAPI-Datei?

Unter paths steht jeder Endpunkt mit Methode, Parametern, Body und Antworten. Unter components stehen wiederverwendbare Schemas, Parameter und Antworten, auf die an anderen Stellen mit $ref verwiesen wird. siehe Abschnitt „Der API-Vertrag mit OpenAPI“


Hinweis zur Nachnutzung als Open Educational Resource (OER)

Dieser Artikel und seine Texte, Bilder, Grafiken, Code und sonstiger Inhalt sind - sofern nicht anders angegeben - lizenziert unter CC BY 4.0. Nennung gemäß TULLU-Regel bitte wie folgt: “Vom Auftrag zur API: Anforderungen und OpenAPI-Vertrag für das Mitfahrlabor-Backend” von oer-informatik.de (H. Stein), Lizenz: CC BY 4.0. Der Artikel wurde unter https://oer-informatik.de/spring-boot-anforderungen-api-entwurf veröffentlicht, die Quelltexte sind in weiterverarbeitbarer Form verfügbar im Repository unter https://gitlab.com/oer-informatik/java-springboot/Backend. Erstellt mit KI-Assistenz; von mir umfassend redaktionell überarbeitet, geprüft und freigegeben. Stand: 11.11.2026.

[Kommentare zum Artikel lesen, schreiben] / [Artikel teilen] / [gitlab-Issue zum Artikel schreiben]

Kommentare gerne per Mastodon, Verbesserungsvorschläge per gitlab issue (siehe oben). Beitrag teilen: