Übungsaufgaben zu Anforderungen und API-Vertrag: Mitfahrgesuche planen

https://bildung.social/@oerinformatik/

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

OpenAPI, API-Entwurf, User Story, Abnahmekriterien, V-Modell, HTTP-Statuscodes, Zustandsdiagramm, REST-API, Übungsaufgaben, Prüfungsvorbereitung

tl/dr; (ca. 71 min Lese- und Bearbeitungszeit): Das MVP der Mitfahr-App kennt nur Angebote. In diesen Übungen planst Du die Ressource „Gesuch“ für alle, die kein Auto haben: Du ordnest Entwurf und Test im V-Modell zu, wählst Methoden und Statuscodes, schreibst User Story und Abnahmekriterien, entwirfst Endpunkte und Schemas im OpenAPI-Vertrag, findest Fehler in einem Vertragsausschnitt und zeichnest die Zustände eines Gesuchs [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

Diese Übungsaufgaben gehören zum Artikel Vom Auftrag zur API: Anforderungen und OpenAPI-Vertrag. Alle Aufgaben spielen in der Mitfahr-App Mitfahrlabor. Den vollständigen Vertrag des MVP findest Du als openapi.yaml.

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

Hinweise zur Bearbeitung: Bis zur Teil-1-Prüfung der IT-Berufe solltest Du die Basiskompetenz beherrschen, also Aufgabe 1.1 und Aufgabe 1.2. Als FIA, FIDP oder FIDV musst Du zur Teil-2-Prüfung Aufgaben auf Kernkompetenz-Ebene lösen können, das sind Aufgabe 2.1, Aufgabe 2.2 und Aufgabe 2.3. Von FIA wird zusätzlich erwartet, dass ihnen Aufgaben auf Profilkompetenz-Ebene (Aufgabe 3.1 und Aufgabe 3.2) keine Probleme bereiten. Notiere Deine Antworten zuerst vollständig, bevor Du die Beispiellösung aufklappst. Für YAML-Antworten kannst Du den Swagger Editor nutzen, um die Syntax zu prüfen; andere fachlich richtige Lösungen sind ebenso richtig.

Du möchtest eigene Aufgaben zum Üben von einem KI-Sprachmodell generieren lassen?

Kopiere den Text in ein KI-Sprachmodell Deiner Wahl und passe Kompetenzstufe, Anzahl, Bearbeitungszeit und Szenario bei Bedarf an. Wie die Aufgaben aufgebaut sind, beschreibt der Artikel Wie sind die Aufgaben aufgebaut?. Prüfe die Ergebnisse mit dem Lehrartikel: KI-Sprachmodelle machen Fehler.

Erstelle neue Übungsaufgaben zum Thema „Anforderungen und API-Vertrag:
Mitfahrgesuche planen“.

Bauplan: Halte Dich an Aufbau, Kompetenzstufen, Operatoren,
Anforderungsbereiche, Punkte und Zeitschätzung, die im Artikel
https://oer-informatik.de/aufgaben-aufbau beschrieben sind.

Fachliche Grundlage:
- https://oer-informatik.de/spring-boot-anforderungen-api-entwurf
- https://oer-informatik.de/szenario-mitfahrlabor
- https://oer-informatik.de/rest-grundlagen
- https://oer-informatik.de/v-modell
- Stilbeispiel: https://oer-informatik.de/spring-boot-anforderungen-api-entwurf-uebungsaufgaben

Die Aufgaben sollen Inhalte zu diesen Schlagwörtern abdecken:
- OpenAPI
- API-Entwurf
- User Story
- Abnahmekriterien
- V-Modell
- HTTP-Statuscodes
- Zustandsdiagramm
- REST-API

Kompetenzstufe: Kernkompetenz (alternativ: Basiskompetenz, Profilkompetenz, Expertise)
Anzahl: 1 Aufgabe mit Teilaufgaben
Bearbeitungszeit in Minuten ca.: <5 bis 30 min>
Szenario: eines der Szenarien aus dem Bauplan

Vorgehen:
1. Lies zuerst die verlinkten Artikel. Kannst Du keine Webseiten
   abrufen, sag mir das, statt zu raten.
2. Steht bei einer Angabe noch ein Platzhalter in <…>, frag mich
   zuerst danach. Richte Punkte und Zahl der Teilaufgaben nach der
   Bearbeitungszeit (ca. 0,9 min je Punkt).
3. Gib je Aufgabe Titel mit Kompetenzstufe, Ausgangssituation und
   Teilaufgaben mit Operator und Punktzahl aus, dazu die geschätzte
   Bearbeitungszeit.
4. Gib die Beispiellösungen mit Punkteverteilung erst aus, wenn ich
   danach frage.

Aufgabe 1.1: Entwurf und Test zuordnen (Basiskompetenz)

Das Projektteam des Mitfahrlabors legt für die neue Ressource „Gesuch“ mehrere Ergebnisse an. Ordne jedes Ergebnis der Entwurfsstufe des V-Modells zu, zu der es gehört, und nenne die Testebene, die es später prüft. (8 Punkte)

Ergebnisse für die Ressource Gesuch
Ergebnis Entwurfsstufe Testebene
Zustandsdiagramm eines Gesuchs mit den Zuständen offen, vermittelt, zurückgezogen, abgelaufen
„Angenommen, Oksana Melnyk hat kein offenes Gesuch für Montag. Wenn sie ein Gesuch für Montag einstellt, dann ist es offen.“
Endpunkt POST /gesuche mit Schema GesuchNeu in openapi.yaml
Festlegung: Das neue Paket service nutzt ein GesuchRepository aus dem Paket repository.

Je Zeile 2 Punkte (1 Punkt Entwurfsstufe, 1 Punkt Testebene):

Ergebnis Entwurfsstufe Testebene
Zustandsdiagramm eines Gesuchs Modulentwurf Komponententest
Abnahmekriterium „Angenommen … Wenn … Dann …“ Anforderungen Abnahmetest
Endpunkt POST /gesuche im Vertrag Systementwurf Systemtest
Abhängigkeit service → repository Architekturentwurf Integrationstest

Aufgabe 1.2: Methoden, Pfade und Statuscodes wählen (Basiskompetenz)

Die Mitfahrlabor-API aus dem Lehrartikel erhält die folgenden Anfragen. Notiere jeweils Methode und Pfad (ohne /v1) sowie den Statuscode, den das Backend antwortet. (12 Punkte)

Anfragen an die Mitfahrlabor-API
Nr. Situation Methode und Pfad Statuscode
1 Aylin Kaya fragt einen Platz im offenen Angebot 4 an. Alles ist in Ordnung.
2 Die App lädt die Daten von Haltepunkt 9. Diesen Haltepunkt gibt es nicht.
3 Marie Schulz sagt ihr Angebot 4 ab.
4 Ben Richter bestätigt Buchung 12. Sein Angebot hat aber keinen freien Platz mehr.
5 Ben Richter bietet eine Fahrt ab Gütersloh (18,6 km) für 2,00 Euro an.
6 Ein neues Angebot wird ohne das Feld datum gesendet.

Je Zeile 2 Punkte (1 Punkt Methode und Pfad, 1 Punkt Statuscode):

Nr. Methode und Pfad Statuscode
1 POST /angebote/4/buchungen 201 Created
2 GET /haltepunkte/9 404 Not Found
3 PATCH /angebote/4 mit {"status": "abgesagt"} 200 OK
4 PATCH /buchungen/12 mit {"status": "bestaetigt"} 409 Conflict (passt nicht zum aktuellen Zustand)
5 POST /angebote 422 Unprocessable Content (höchstens 1,86 Euro erlaubt)
6 POST /angebote 400 Bad Request (Pflichtfeld fehlt, Vertrag verletzt)

Aufgabe 2.1: Das Mitfahrgesuch als User Story (Kernkompetenz)

Oksana Melnyk hat kein Auto und arbeitet selbst im Projektteam. Sie schlägt vor, dass Auszubildende ohne Auto ein Gesuch einstellen können: Haltepunkt, Richtung, Datum und ein Zeitfenster (frühestens, spätestens). Fahrer*innen sehen die Gesuche und können gezielt eine Fahrt anbieten. Andrea Wolf, die Datenschutzbeauftragte, ergänzt: „Für Gesuche gelten dieselben Regeln für Minderjährige wie für Buchungen. Und pro Tag und Richtung braucht niemand mehr als ein offenes Gesuch.“

a) Notiere die Anforderung als User Story. (2 Punkte)

Als Mitfahrende*r ohne Auto möchte ich ein Gesuch mit Haltepunkt, Richtung, Datum und Zeitfenster einstellen, damit Fahrer*innen sehen, dass ich eine Mitfahrgelegenheit brauche. (Rolle, Ziel, Nutzen je 1 Punkt, höchstens 2 Punkte; andere Formulierungen mit allen drei Teilen sind richtig.)

b) Formuliere drei Abnahmekriterien in der Form Angenommen – Wenn – Dann. Mindestens zwei davon sollen einen Fehlerfall beschreiben. (6 Punkte)

Je Kriterium 2 Punkte (vollständige Form 1 Punkt, überprüfbares Ergebnis 1 Punkt), zum Beispiel:

  • AK-G.1: Angenommen, Oksana Melnyk hat für Montag in Richtung „zur Schule“ noch kein offenes Gesuch. Wenn sie für Montag ein Gesuch ab Gütersloh mit dem Zeitfenster 06:45 bis 07:15 Uhr einstellt, dann ist das Gesuch gespeichert und „offen“.

  • AK-G.2: Angenommen, eine Mitfahrerin ist am Tag der Fahrt noch nicht 18 und es liegt keine Einwilligung der Eltern vor. Wenn sie ein Gesuch einstellt, dann wird es abgelehnt.

  • AK-G.3: Angenommen, Oksana Melnyk hat für Montag in Richtung „zur Schule“ bereits ein offenes Gesuch. Wenn sie ein zweites für denselben Tag und dieselbe Richtung einstellt, dann wird es abgelehnt.

Weitere richtige Fehlerfälle: Zeitfenster mit Ende vor dem Beginn, Datum in der Vergangenheit, unbekannter Haltepunkt.

c) Entscheide für die folgenden Regeln, ob schon der API-Vertrag sie prüfen kann oder erst das Backend. Begründe jeweils kurz. (4 Punkte)

  • Das Datum ist angegeben.
  • Das Zeitfenster beginnt vor seinem Ende.
  • Minderjährige brauchen eine Einwilligung.
  • Pro Tag und Richtung gibt es höchstens ein offenes Gesuch je Person.

Je Regel 1 Punkt:

  • Datum angegeben: Vertrag (required), denn das sieht man der Anfrage allein an.
  • Zeitfenster: Backend. Beide Werte stehen zwar in der Anfrage, aber ein OpenAPI-3.0-Schema kann zwei Felder nicht miteinander vergleichen. (Wer argumentiert, dass dies eine einfache Prüfung im Controller oder in einer eigenen Validierungsannotation ist, liegt ebenfalls richtig, solange klar ist, dass openapi.yaml sie nicht ausdrückt.)
  • Einwilligung: Backend, braucht Geburtsdatum und Einwilligung aus den gespeicherten Daten der Person.
  • Ein offenes Gesuch: Backend, braucht die schon gespeicherten Gesuche der Person.

Aufgabe 2.2: Endpunkte für Gesuche entwerfen (Kernkompetenz)

Die API soll folgende Funktionen für Gesuche anbieten: ein Gesuch einstellen, offene Gesuche nach Datum, Richtung und Haltepunkt suchen, ein einzelnes Gesuch abrufen und ein Gesuch zurückziehen. Außerdem sollen die Flurmonitore neben Angeboten auch offene Gesuche zeigen.

a) Lege für die vier Funktionen Methode, Pfad, Statuscode bei Erfolg und mögliche Fehlercodes fest. Halte Dich an die Regeln, nach denen die vorhandenen Endpunkte gebaut sind. (8 Punkte)

Je Funktion 2 Punkte (Methode und Pfad 1 Punkt, Codes 1 Punkt):

Funktion Methode und Pfad Erfolg Fehler
einstellen POST /gesuche 201 mit Location 400, 404 (Haltepunkt unbekannt), 422 (Einwilligung, zweites offenes Gesuch)
suchen GET /gesuche?datum=…&richtung=…&haltepunkt=… 200 (auch leere Liste) 400
abrufen GET /gesuche/{gesuchId} 200 404
zurückziehen PATCH /gesuche/{gesuchId} mit {"status": "zurueckgezogen"} 200 400, 404, 409 (nicht mehr offen)

Auch 409 statt 422 für ein zweites offenes Gesuch lässt sich begründen, weil es um einen Konflikt mit vorhandenen Daten geht.

b) Begründe, warum das Zurückziehen nicht mit DELETE /gesuche/{gesuchId} umgesetzt wird. (2 Punkte)

Zurückziehen ist ein Zustandswechsel. Das Gesuch soll erhalten bleiben, damit Fahrer*innen, die es gerade ansehen, den Hinweis „zurückgezogen“ statt „nicht gefunden“ erhalten und damit später nachvollziehbar ist, wie viele Gesuche vermittelt wurden. PATCH ändert nur den Status. (Begründung mit Zustandswechsel 1 Punkt, Folge für Nutzende oder Auswertung 1 Punkt)

c) Beschreibe, was sich am Schema MonitorEintrag im Vertrag ändern muss, damit die Monitore auch Gesuche anzeigen. (2 Punkte)

Das Feld art bekommt einen weiteren erlaubten Wert: enum: [Angebot, Gesuch] (1 Punkt). Für ein Gesuch steht unter zeit der Beginn des Zeitfensters und unter plaetze die Zahl 1, so wie in der View v_monitor des Szenarios; das wird in der Beschreibung des Schemas festgehalten (1 Punkt). Namen und Pseudonyme bleiben weiterhin ausgeschlossen.

Aufgabe 2.3: Gesuche im OpenAPI-Vertrag beschreiben (Kernkompetenz)

a) Notiere unter components/schemas die Schemas GesuchNeu (Body beim Einstellen) und Gesuch (Antwort mit id und status). Verwende dabei die vorhandenen Schemas wieder, wo es passt. (8 Punkte)

components:
  schemas:
    GesuchStatus:
      type: string
      enum: [offen, vermittelt, zurueckgezogen, abgelaufen]

    GesuchNeu:
      type: object
      required: [mitfahrerId, haltepunktId, richtung, datum, zeitVon, zeitBis]
      properties:
        mitfahrerId:
          type: integer
          format: int64
        haltepunktId:
          type: integer
          format: int64
        richtung:
          $ref: '#/components/schemas/Richtung'
        datum:
          type: string
          format: date
        zeitVon:
          type: string
          pattern: '^([01][0-9]|2[0-3]):[0-5][0-9]$'
        zeitBis:
          type: string
          pattern: '^([01][0-9]|2[0-3]):[0-5][0-9]$'
          description: muss nach zeitVon liegen (prüft das Backend)

    Gesuch:
      allOf:
        - $ref: '#/components/schemas/GesuchNeu'
        - type: object
          required: [id, status]
          properties:
            id:
              type: integer
              format: int64
            status:
              $ref: '#/components/schemas/GesuchStatus'

Bewertung: Pflichtfelder vollständig (2 Punkte), Typen und Formate passend (2 Punkte), Richtung per $ref wiederverwendet (1 Punkt), Uhrzeiten mit Muster (1 Punkt), Gesuch mit id und status (2 Punkte). Gesuch darf auch ohne allOf mit allen Feldern notiert werden.

b) Notiere unter paths den Endpunkt zum Einstellen eines Gesuchs mit operationId, Body und allen Antworten. Nutze die vorhandenen Antworten unter components/responses. (4 Punkte)

paths:
  /gesuche:
    post:
      tags: [gesuche]
      operationId: stelleGesuchEin
      summary: ein Mitfahrgesuch einstellen
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GesuchNeu'
      responses:
        '201':
          description: Gesuch angelegt
          headers:
            Location:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Gesuch'
        '400':
          $ref: '#/components/responses/UngueltigeAnfrage'
        '404':
          $ref: '#/components/responses/NichtGefunden'
        '422':
          $ref: '#/components/responses/FachregelVerletzt'

Bewertung: Pfad, Methode und operationId (1 Punkt), Body mit $ref auf GesuchNeu (1 Punkt), 201 mit Gesuch (1 Punkt), Fehlerantworten (1 Punkt).

Aufgabe 3.1: Fehler im Vertrag finden (Profilkompetenz)

Ein Teammitglied hat einen ersten Entwurf für die Gesuche geschrieben. Der Ausschnitt enthält sechs Fehler: Verstöße gegen die OpenAPI-Spezifikation, gegen die Regeln der HTTP-Methoden und gegen die Entwurfsregeln der Mitfahrlabor-API.

paths:
  /gesuche/{id}:
    get:
      tags: [gesuche]
      operationId: holeGesuch
      parameters:
        - name: gesuchId
          in: path
          required: false
          schema:
            type: integer
            format: int64
      responses:
        '201':
          description: das Gesuch
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Gesuch'
  /gesuche/zurueckziehen:
    get:
      tags: [gesuche]
      operationId: holeGesuch
      parameters:
        - name: gesuchId
          in: query
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: zurückgezogen

Benenne die sechs Fehler, begründe jeweils, warum es ein Fehler ist, und gib eine Korrektur an. (12 Punkte)

Je Fehler 2 Punkte (Fehler mit Begründung 1 Punkt, Korrektur 1 Punkt):

  1. Parametername passt nicht zum Platzhalter: Der Pfad enthält {id}, der Parameter heißt gesuchId. OpenAPI verlangt, dass jeder Platzhalter im Pfad einen gleichnamigen Pfadparameter hat. Korrektur: Pfad /gesuche/{gesuchId}.

  2. Pfadparameter optional: Pfadparameter müssen required: true haben, denn ohne sie gibt es den Pfad nicht. Korrektur: required: true.

  3. Falscher Erfolgscode: GET liest nur und legt nichts an; 201 Created passt nicht. Korrektur: '200'.

  4. operationId doppelt: holeGesuch kommt zweimal vor. Die operationId muss in der ganzen Datei eindeutig sein, weil daraus Methodennamen erzeugt werden. Korrektur: für die zweite Operation z. B. zieheGesuchZurueck.

  5. Verb im Pfad und ID als Query-Parameter: /gesuche/zurueckziehen benennt eine Aktion statt einer Ressource. Korrektur: PATCH /gesuche/{gesuchId} mit {"status": "zurueckgezogen"}.

  6. GET ändert den Zustand: GET muss safe sein, sonst ziehen Crawler, Caches oder ein erneutes Laden der Seite Gesuche zurück. Korrektur: PATCH (siehe 5.)

Ebenfalls richtig erkannt (als Ersatz für einen der sechs, ohne Extrapunkte): Für ein unbekanntes Gesuch fehlt die Antwort 404; nach den Entwurfsregeln der API hat jeder Abruf über eine ID diese Antwort. Korrektur: '404': $ref: '#/components/responses/NichtGefunden'.

Aufgabe 3.2: Die Zustände eines Gesuchs modellieren (Profilkompetenz)

Ein Gesuch beginnt als „offen“. Bestätigt eine Fahrerin eine Buchung, die aus dem Gesuch entstanden ist, ist es „vermittelt“. Die Person, die das Gesuch eingestellt hat, kann ein offenes Gesuch zurückziehen. Ist der Tag des Gesuchs vorbei, ohne dass es vermittelt wurde, ist es „abgelaufen“. Vermittelte, zurückgezogene und abgelaufene Gesuche ändern sich nicht mehr.

a) Zeichne das UML-Zustandsdiagramm eines Gesuchs mit Start- und Endzustand, Zuständen und Transitionen samt Auslösern. (8 Punkte)

UML-Zustandsdiagramm eines Gesuchs: vom Start nach offen; von offen mit buchungBestaetigt() nach vermittelt, mit zurueckziehen() nach zurückgezogen und mit dem Änderungsereignis when(datum < heute) nach abgelaufen; alle drei enden (mit KI erstellt)

Bewertung: Start nach „offen“ (1 Punkt), vier Zustände (2 Punkte), drei Transitionen mit passenden Auslösern (3 Punkte), Ablauf als Zeit- oder Änderungsereignis, z. B. when(datum < heute) (1 Punkt), Endzustände (1 Punkt).

b) Nenne eine Regel, die das Zustandsdiagramm des Gesuchs mit dem der Buchung verbindet, und erläutere, in welcher Schicht des Backends sie umgesetzt wird. (2 Punkte)

Wenn eine Buchung, die aus einem Gesuch entstanden ist, den Zustand „bestätigt“ erreicht, wechselt das Gesuch nach „vermittelt“ (1 Punkt). Weil dabei zwei Objekte gemeinsam geändert und gespeichert werden, gehört die Regel in den Service, der beide in einer Transaktion ändert (1 Punkt). Wer stattdessen die Domäne nennt und begründet, dass der Service nur aufruft, liegt ebenfalls richtig.


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: “Übungsaufgaben zu Anforderungen und API-Vertrag: Mitfahrgesuche planen” von oer-informatik.de (H. Stein), Lizenz: CC BY 4.0. Der Artikel wurde unter https://oer-informatik.de/spring-boot-anforderungen-api-entwurf-uebungsaufgaben 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: