DEV Community

Cover image for Spec-First API Entwicklung: Was ist das?
Emre Demir
Emre Demir

Posted on • Originally published at apidog.com

Spec-First API Entwicklung: Was ist das?

Die meisten API-Fehler entstehen nicht durch schlechten Code, sondern durch unklare Verträge. Das Frontend erwartet userId, das Backend liefert user_id, und der Fehler fällt erst in der Qualitätssicherung auf. Spec-First API-Entwicklung verhindert das: Sie schreiben zuerst den API-Vertrag und implementieren danach gegen diese Vereinbarung.

Teste Apidog noch heute

In diesem Leitfaden erstellen Sie eine kleine OpenAPI-Spezifikation für /users und verwenden dieselbe Datei für Mocks, Tests und Dokumentation, bevor Servercode existiert. Der Ansatz heißt auch Spec-Driven Development, Design-First oder Contract-First. Gemeint ist immer dasselbe: Erst die Schnittstelle festlegen, dann bauen.

Was Spec-First API-Entwicklung bedeutet

Spec-First API-Entwicklung bedeutet: Sie schreiben einen maschinenlesbaren Vertrag, typischerweise ein OpenAPI-Dokument, bevor Sie den Endpunkt implementieren.

Dieser Vertrag beschreibt:

  • Pfade
  • Parameter
  • Request Bodies
  • Response Bodies
  • Statuscodes
  • Schemas
  • Fehlerfälle

Die Spezifikation ist damit nicht nachträgliche Dokumentation. Sie ist die Quelle der Wahrheit.

Praktisch heißt das:

  • Das Frontend entwickelt gegen einen Mock aus der Spezifikation.
  • Die Qualitätssicherung schreibt Tests gegen denselben Vertrag.
  • Das Backend implementiert die Endpunkte so, dass sie die Spezifikation erfüllen.
  • Die Dokumentation wird aus derselben Datei gerendert.

Damit verschieben Sie Integrationsprobleme an den Anfang des Projekts, wo Änderungen noch günstig sind.

Spec-First vs. Code-First im Lebenszyklus

Beide Ansätze können dieselben Endpunkte erzeugen. Der Unterschied liegt darin, wann Fehler sichtbar werden und wer parallel arbeiten kann.

Spec-First vs. Code-First Lebenszyklus

Bei Code-First entsteht der Vertrag oft erst nach der Implementierung. Bei Spec-First existiert der Vertrag zuerst. Dadurch können Frontend, Backend und QA gleichzeitig mit derselben Definition arbeiten.

OpenAPI-Beispiel: /users Schritt für Schritt

Wir entwerfen einen kleinen /users-Endpunkt mit:

  • GET /users zum Auflisten von Benutzern
  • POST /users zum Erstellen eines Benutzers
  • gemeinsamem User-Schema
  • Query-Parameter limit
  • Erfolgs- und Fehlerantworten

1. OpenAPI-Grundstruktur anlegen

Erstellen Sie eine Datei, zum Beispiel openapi.yaml:

openapi: 3.0.3
info:
  title: Users API
  version: 1.0.0
servers:
  - url: https://api.example.com/v1
Enter fullscreen mode Exit fullscreen mode

Damit definieren Sie die OpenAPI-Version, Metadaten und die Basis-URL.

2. Gemeinsames User-Schema definieren

Legen Sie wiederverwendbare Schemas unter components/schemas ab:

components:
  schemas:
    User:
      type: object
      required: [id, email, createdAt]
      properties:
        id:
          type: string
          format: uuid
        email:
          type: string
          format: email
        name:
          type: string
        createdAt:
          type: string
          format: date-time
Enter fullscreen mode Exit fullscreen mode

Wichtig:

  • required definiert Pflichtfelder.
  • format: uuid, format: email und format: date-time helfen Tools bei Validierung, Mocking und Dokumentation.
  • Das Schema kann später mit $ref wiederverwendet werden.

3. GET /users spezifizieren

Fügen Sie den Listen-Endpunkt hinzu:

paths:
  /users:
    get:
      summary: List users
      operationId: listUsers
      parameters:
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
            maximum: 100
      responses:
        "200":
          description: A list of users
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/User"
Enter fullscreen mode Exit fullscreen mode

Der Vertrag legt hier fest:

  • limit ist ein Query-Parameter.
  • Der Standardwert ist 20.
  • Der Maximalwert ist 100.
  • Die Antwort ist ein Array von User-Objekten.

4. POST /users spezifizieren

Ergänzen Sie unter /users den post-Vorgang:

    post:
      summary: Create a user
      operationId: createUser
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [email]
              properties:
                email:
                  type: string
                  format: email
                name:
                  type: string
      responses:
        "201":
          description: User created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"
        "400":
          description: Invalid request body
Enter fullscreen mode Exit fullscreen mode

Damit ist eindeutig:

  • Der Client muss JSON senden.
  • email ist erforderlich.
  • Bei Erfolg kommt 201.
  • Der Response Body entspricht dem User-Schema.
  • Ungültige Requests erhalten 400.

5. Vollständige Spezifikation

Zusammen ergibt sich:

openapi: 3.0.3
info:
  title: Users API
  version: 1.0.0

servers:
  - url: https://api.example.com/v1

paths:
  /users:
    get:
      summary: List users
      operationId: listUsers
      parameters:
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
            maximum: 100
      responses:
        "200":
          description: A list of users
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/User"

    post:
      summary: Create a user
      operationId: createUser
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [email]
              properties:
                email:
                  type: string
                  format: email
                name:
                  type: string
      responses:
        "201":
          description: User created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"
        "400":
          description: Invalid request body

components:
  schemas:
    User:
      type: object
      required: [id, email, createdAt]
      properties:
        id:
          type: string
          format: uuid
        email:
          type: string
          format: email
        name:
          type: string
        createdAt:
          type: string
          format: date-time
Enter fullscreen mode Exit fullscreen mode

Noch ist kein Servercode geschrieben. Trotzdem steht fest, welche Felder erlaubt sind, welche Felder erforderlich sind, welche Statuscodes erwartet werden und wie Responses aussehen müssen.

Mocks, Tests und Dokumentation aus der Spezifikation erzeugen

Der Nutzen von Spec-First entsteht dadurch, dass eine Datei mehrere Artefakte steuert.

Mock-Server starten

Ein Mock-Server liest die OpenAPI-Datei und erzeugt Antworten, die zu den Schemas passen.

Beispiel:

GET /users?limit=2
Enter fullscreen mode Exit fullscreen mode

Eine passende Mock-Antwort könnte so aussehen:

[
  {
    "id": "7e5a2c3e-4e63-4df5-b642-2b6f9c5c7b4a",
    "email": "user@example.com",
    "name": "Example User",
    "createdAt": "2026-06-02T10:00:00Z"
  }
]
Enter fullscreen mode Exit fullscreen mode

Dadurch kann das Frontend sofort integrieren, auch wenn der echte Backend-Handler noch nicht existiert.

Vertragstests ableiten

Die Spezifikation ist auch ein Testorakel. Sie definiert, was gültig ist.

Typische Vertragstests prüfen:

  • Gibt POST /users bei gültigem Body 201 zurück?
  • Entspricht der Response Body dem User-Schema?
  • Gibt POST /users bei fehlender email einen 400 zurück?
  • Wird limit > 100 abgelehnt oder korrekt behandelt?
  • Enthält GET /users ein Array von User-Objekten?

Sie testen damit nicht frei erfundene Annahmen, sondern den bereits vereinbarten Vertrag.

Dokumentation generieren

Die API-Referenz wird direkt aus openapi.yaml erstellt. Jeder Pfad, Parameter, Statuscode und jedes Schema stammt aus derselben Quelle.

Das verhindert doppelte Pflege:

  • keine separate Markdown-Dokumentation für dieselben Endpunkte
  • keine manuell synchronisierten Response-Beispiele
  • weniger Drift zwischen Implementierung, Tests und Dokumentation

Spec-First passt deshalb gut zu einem Git-nativen API-Workflow: Die Spezifikation ist eine Textdatei. Jede Vertragsänderung wird als Diff im Pull Request sichtbar.

Spec-First in Apidog umsetzen

Apidog unterstützt diesen Ablauf mit dem Spec-First-Modus. Die OpenAPI-Datei ist dabei nicht nur ein Export, sondern das zentrale Projektartefakt.

Spec-First-Modus in Apidog

Ein praktischer Ablauf sieht so aus:

  1. Repository mit openapi.yaml vorbereiten.
  2. Spezifikation in Apidog öffnen oder einfügen.
  3. /users-Definition im Editor bearbeiten.
  4. Mock-Server aus der Spezifikation starten.
  5. Frontend gegen den Mock entwickeln lassen.
  6. Dokumentation automatisch aus derselben Datei rendern.
  7. Backend implementieren.
  8. Operationen aus der Spezifikation als Tests gegen das echte Backend ausführen.
  9. Änderungen per Git synchronisieren und im Pull Request prüfen.

Der wichtige Punkt ist die bidirektionale Git-Synchronisierung. Änderungen an der YAML-Datei können aus dem Repository nach Apidog fließen. Änderungen in Apidog können wiederum als Commit überprüft werden. So bleibt der Vertrag an einer Stelle versioniert und nachvollziehbar.

Wenn Sie den Unterschied zu einem klassischen Design-First-Workflow genauer vergleichen möchten, lesen Sie Spec-First vs. Design-First in Apidog.

Spec-First-Checkliste für die Implementierung

Bevor Sie mit der Backend-Implementierung starten, prüfen Sie die Spezifikation:

  • [ ] Die OpenAPI-Datei ist gegen das OpenAPI-Schema validiert.
  • [ ] Jeder Endpunkt hat mindestens eine Erfolgsantwort.
  • [ ] Jeder Endpunkt hat mindestens eine Fehlerantwort.
  • [ ] Gemeinsame Objekte liegen unter components/schemas.
  • [ ] Wiederverwendbare Strukturen werden mit $ref referenziert.
  • [ ] Pflichtfelder sind mit required markiert.
  • [ ] Formate wie uuid, email und date-time sind gesetzt, wo sie zutreffen.
  • [ ] Query-Parameter haben klare Typen, Defaults und Grenzen.
  • [ ] Die Spezifikation liegt in Git.
  • [ ] Änderungen werden per Pull Request geprüft.
  • [ ] Ein Mock-Server läuft aus derselben Spezifikation.
  • [ ] Das Frontend kann den Mock verwenden.
  • [ ] Vertragstests prüfen echte Responses gegen die Schemas.
  • [ ] Die veröffentlichte Dokumentation wird aus derselben Datei gerendert.

Wenn diese Punkte erfüllt sind, arbeiten Teams nicht mehr gegen Vermutungen, sondern gegen eine gemeinsame Vereinbarung.

FAQ

Ist Spec-First API-Entwicklung dasselbe wie Design-First?

Meistens ja. „Design-First“ und „Contract-First“ beschreiben dasselbe Prinzip: Die Schnittstelle wird vor der Implementierung festgelegt. „Spec-First“ betont, dass die OpenAPI-Spezifikation das konkrete Startartefakt ist.

Muss ich YAML von Hand schreiben?

Nein. Sie können eine Spezifikation in einem visuellen Editor erstellen und daraus YAML erzeugen lassen. Sie können die YAML aber auch direkt bearbeiten. Entscheidend ist nicht das Eingabeformat, sondern dass der Vertrag vor dem Code existiert und abgestimmt ist.

Wie verhindere ich, dass Spezifikation und Code auseinanderdriften?

Machen Sie die Spezifikation zur Quelle der Wahrheit:

  • Spezifikation in Git versionieren
  • Änderungen per Pull Request prüfen
  • Vertragstests in CI ausführen
  • Dokumentation aus derselben Datei generieren
  • Mock-Server aus derselben Datei betreiben

Wenn eine echte Response nicht mehr zum Schema passt, sollte der Build fehlschlagen.

Fazit

Spec-First API-Entwicklung ändert nicht, was Sie bauen. Sie ändert die Reihenfolge: Erst Vertrag, dann Implementierung.

Das Ergebnis ist ein klarerer Workflow für Frontend, Backend und QA. Eine OpenAPI-Datei liefert Mock, Tests und Dokumentation aus derselben Quelle. Wenn Sie den Workflow ausprobieren möchten, öffnen Sie den Spec-First-Modus in Apidog und verbinden Sie ihn mit Ihrem Repository.

Top comments (0)