API-Dokumentations-Generator
Extrahiert API-Dokumentation aus vorhandenem Route-Handler-Code. Liest Ihren Quellcode, leitet Schemata ab und erzeugt OpenAPI-Spezifikationen, TypeScript-Typen und ausführbare curl-Beispiele – nicht aus Designabsicht, sondern aus der tatsächlichen Implementierung.
Aktivierungs-Trigger
Aktivieren bei: „API-Dokumentation generieren“, „OpenAPI aus Code“, „Endpunkte dokumentieren“, „API-Referenz“, „Swagger-Generierung“, „Endpunkt-Dokumentation“, „API-Typen erstellen“, „curl-Beispiele für API“
NICHT für: API-Design von Grund auf --> api-architect | OpenAPI-Authoring ohne Quellcode --> openapi-spec-writer | API-Tests --> test-automation-expert
Kernfunktionen
- Extrahiert Routendefinitionen aus Express, Next.js App Router, Next.js Pages API-Routen, Fastify und Hono-Handlern
- Leitet Request/Response-Schemata aus TypeScript-Typen, Zod-Schemata oder Runtime-Validierung ab
- Generiert OpenAPI 3.0/3.1-Spezifikationen mit korrekten Pfadparametern, Query-Strings und Request-Bodies
- Erzeugt TypeScript-Typdefinitionen, die dem tatsächlichen API-Vertrag entsprechen
- Erstellt curl-Beispiele für jeden Endpunkt mit realistischen Beispieldaten
- Dokumentiert Authentifizierungsanforderungen durch Nachverfolgung von Middleware-Ketten
- Identifiziert Rate-Limiting-Konfiguration und dokumentiert Limits pro Endpunkt
- Katalogisiert Fehlerantworten durch Analyse von Throw/Return-Mustern in Handlern
- Erkennt undokumentierte Endpunkte (Routen, die existieren, aber kein JSDoc oder Schema haben)
Framework-Erkennung
Vor der Generierung muss das Framework identifiziert werden. Die Extraktionsstrategie unterscheidet sich erheblich.
Express / Express-ähnlich
Signale: app.get(), router.post(), express.Router()
Routenquelle: app._router.stack oder explizite Router-Dateien
Middleware-Kette: Reihenfolge von app.use() ist wichtig für Auth-Erkennung
Achten Sie auf Routen-Registrierungsmuster:
router.get('/users/:id', authenticate, getUser)– Middleware vor Handler bedeutet Auth erforderlichapp.use('/api/v1', rateLimiter({ max: 100 }), apiRouter)– Rate-Limiter auf Teilbaum angewendet
Next.js App Router
Signale: route.ts-Dateien, die GET, POST, PUT, DELETE, PATCH exportieren
Routenquelle: Dateisystem-Konvention in app/api/
Middleware-Kette: middleware.ts an Verzeichnisgrenzen
Pfadparameter stammen aus Ordnernamen: app/api/users/[id]/route.ts --> /api/users/{id}
Next.js Pages API-Routen
Signale: pages/api/**/*.ts mit default export handler
Routenquelle: Dateisystem-Konvention
Methoden-Routing: req.method-switch innerhalb des Handlers
Fastify
Signale: fastify.get(), fastify.route(), schema-Eigenschaft auf Routenoptionen
Routenquelle: Plugin-Registrierung mit fastify.register()
Schema: Fastify-Routen haben oft bereits JSON-Schema – extrahieren und konvertieren
Fastify ist das am einfachsten zu dokumentierende Framework, da Routen häufig ihre eigenen Schemata deklarieren. Priorisieren Sie die Extraktion vorhandener schema.body, schema.response und schema.querystring, bevor Sie inferieren.
Hono
Signale: app.get(), app.post(), Hono(), zValidator()
Routenquelle: Methodenverkettung auf Hono-Instanz
Validierung: Zod-basiert über zValidator-Middleware
Hono mit zValidator liefert Ihnen direkt Zod-Schemata. Konvertieren Sie Zod --> JSON-Schema --> OpenAPI-Schema.
Extraktionsprozess
Schritt 1: Routen entdecken
Durchsuchen Sie das Projekt nach Routen-Registrierungen. Verlassen Sie sich nicht auf einen einzelnen Einstiegspunkt – Frameworks teilen Routen oft über mehrere Dateien auf.
# Express: Router-Dateien finden
grep -rl "express.Router\|app.get\|app.post\|router\." src/ --include="*.ts" --include="*.js"
# Next.js App Router: Route-Handler finden
find src/app/api -name "route.ts" -o -name "route.js"
# Next.js Pages: API-Routen finden
find src/pages/api -name "*.ts" -o -name "*.js"
# Fastify: Routen-Registrierungen finden
grep -rl "fastify\.\(get\|post\|put\|delete\|route\)" src/ --include="*.ts"
# Hono: Routendefinitionen finden
grep -rl "app\.\(get\|post\|put\|delete\|patch\)" src/ --include="*.ts"
Schritt 2: Schemata extrahieren
Identifizieren Sie für jede Route die Request- und Response-Formen.
Prioritätsreihenfolge für Schemaquellen:
- Explizite Zod/Joi/Yup-Validierungsschemata (höchste Zuverlässigkeit)
- TypeScript-Typannotationen auf Request/Response
- JSON-Schema-Deklarationen (Fastify)
- JSDoc @param / @returns-Annotationen
- Runtime-Inferenz aus der Response-Konstruktion (niedrigste Zuverlässigkeit – als approximativ kennzeichnen)
Bei Verwendung von Runtime-Inferenz (Option 5) markieren Sie das Schema immer mit x-inferred: true in der OpenAPI-Ausgabe, damit Konsumenten wissen, dass es möglicherweise unvollständig ist.
Schritt 3: Authentifizierung nachverfolgen
Gehen Sie die Middleware-Kette für jede Route durch, um Auth-Anforderungen zu ermitteln:
- Keine Auth-Middleware: Markieren als
security: [](öffentlich) - Bearer-Token-Middleware: Markieren als
security: [{ bearerAuth: [] }] - API-Key-Middleware: Markieren als
security: [{ apiKeyAuth: [] }] - Session/Cookie-Auth: Markieren als
security: [{ cookieAuth: [] }] - Mehrere Auth-Optionen: Alle als Alternativen im Security-Array auflisten
Schritt 4: Fehler katalogisieren
Lesen Sie jeden Handler und listen Sie jede Fehlerantwort auf:
res.status(400).json(...)oderthrow new BadRequestError(...)--> 400-Response-Schemares.status(401)--> 401 (auch wenn Auth-Middleware vorhanden ist, ohne explizites Throw)res.status(404)--> 404res.status(409)--> 409 (Konflikt, häufig bei Create-Operationen)res.status(422)--> 422 (Validierungsfehler)res.status(429)--> 429 (Rate-Limited, einschließen, wenn Rate-Limiter-Middleware erkannt wurde)res.status(500)--> 500 (immer als Möglichkeit einschließen)
Schritt 5: Ausgaben generieren
Erzeugen Sie drei Artefakte:
- OpenAPI-Spezifikation (YAML, nicht JSON – lesbarer, einfacher zu diffen)
- TypeScript-Typen (eigenständige
.d.ts-Datei mit allen Request/Response-Typen) - curl-Beispiele (eines pro Endpunkt, mit Headern und Beispiel-Payloads)
Entscheidungspunkte
Wenn die Codebasis keine Validierungsschemata hat
Wenn Handler rohes req.body ohne Zod/Joi-Validierung akzeptieren, müssen Sie Typen aus der Nutzung ableiten. Achten Sie auf:
- Property-Zugriffsmuster:
req.body.name,req.body.email-->{ name: string, email: string } - Destrukturierung:
const { name, email } = req.body--> gleiche Inferenz - Datenbank-Insert-Aufrufe:
db.users.create({ name: body.name })--> DB-Schema referenzieren, falls verfügbar
Kennzeichnen Sie die gesamte Spezifikation mit einer Warnung: x-schemas-inferred: true auf Info-Ebene.
Wenn Routen dynamische Pfadsegmente verwenden
- Express:
:id--> OpenAPI{id} - Next.js:
[id]--> OpenAPI{id} - Next.js Catch-All:
[...slug]--> OpenAPI{slug}mit Hinweis auf Array-Verhalten - Fastify:
:id--> OpenAPI{id} - Hono:
:id--> OpenAPI{id}
Wenn die Response-Form je nach Statuscode variiert
Dokumentieren Sie jeden Statuscode mit seinem eigenen Schema. Führen Sie 200 und 201 nicht in einem Schema zusammen, wenn sie sich unterscheiden. Häufiges Muster:
responses:
'200':
description: Benutzer gefunden
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'404':
description: Benutzer nicht gefunden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
Wenn Rate-Limits pro Endpunkt unterschiedlich sind
Dokumentieren Sie Rate-Limits mit OpenAPI-Erweiterungen:
x-rate-limit:
requests: 100
window: 60s
scope: per-api-key
Wenn der Rate-Limiter global ist (einmal auf App-Ebene angewendet), dokumentieren Sie ihn im info-Bereich der obersten Ebene. Wenn pro Route, dokumentieren Sie ihn auf jeder Operation.
TypeScript-Typ-Generierung
Generieren Sie Typen, die exakt mit der OpenAPI-Spezifikation übereinstimmen. Verwenden Sie gebrandete Typen für IDs, wenn die Codebase sie verwendet.
// Aus OpenAPI-Spezifikation generiert – nicht manuell bearbeiten
export interface CreateUserRequest {
name: string;
email: string;
role?: 'admin' | 'member' | 'viewer';
}
export interface CreateUserResponse {
id: string;
name: string;
email: string;
role: 'admin' | 'member' | 'viewer';
createdAt: string; // ISO 8601
}
export interface ErrorResponse {
error: {
code: string;
message: string;
details?: Array<{
field: string;
issue: string;
}>;
};
}
export interface PaginatedResponse<T> {
data: T[];
meta: {
page: number;
perPage: number;
total: number;
hasMore: boolean;
};
}
Curl-Beispiel-Generierung
Generieren Sie ein curl pro Endpunkt. Verwenden Sie realistische, aber offensichtlich falsche Daten.
# GET /api/users/:id – Einzelnen Benutzer abrufen
curl -X GET https://api.example.com/api/users/usr_abc123 \
-H "Authorization: Bearer sk_test_..." \
-H "Accept: application/json"
# POST /api/users – Neuen Benutzer erstellen
curl -X POST https://api.example.com/api/users \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Ada Lovelace",
"email": "[email protected]",
"role": "member"
}'
# GET /api/users – Benutzer mit Paginierung auflisten
curl -X GET "https://api.example.com/api/users?page=1&perPage=20&role=admin" \
-H "Authorization: Bearer sk_test_..." \
-H "Accept: application/json"
Regeln für curl-Beispiele:
- Immer die vollständige URL angeben (verwenden Sie
https://api.example.comals Basis) - Alle erforderlichen Header einschließen
-dmit formatiertem JSON für Request-Bodies verwenden- URLs mit Query-Parametern in Anführungszeichen setzen
- Die HTTP-Methode auch bei GET explizit angeben
sk_test_...für Auth-Tokens verwenden (offensichtlich gefälscht)- Realistische Feldwerte verwenden, nicht „string“ oder „test“
Anti-Patterns
1. Dokumentation von Wunsch-APIs
Symptom: Spezifikation beschreibt Endpunkte, die im Code noch nicht existieren Fix: Dokumentieren Sie nur, was der Code tatsächlich implementiert. Wenn ein geplanter Endpunkt in Kommentaren oder einer Spezifikationsdatei steht, aber nicht in Handlern, schließen Sie ihn aus.
2. Ignorieren von Middleware-Seiteneffekten
Symptom: Die Dokumentation sagt, ein Endpunkt sei öffentlich, obwohl er tatsächlich Auth über eine übergeordnete Middleware erfordert
Fix: Verfolgen Sie die vollständige Middleware-Kette von der App-Wurzel zum Handler. Ein router.use(auth) oberhalb der Routendefinition bedeutet, dass alle darunter liegenden Routen Auth erfordern.
3. Annahme der Request-Body-Form
Symptom: req.body wird als any oder object dokumentiert, weil es keine Validierung gibt
Fix: Aus der Nutzung ableiten (Property-Zugriff, Destrukturierung, Datenbankaufrufe). Als x-inferred: true markieren. Empfehlen, Zod-Validierung hinzuzufügen.
4. Flache Fehlerdokumentation
Symptom: Jeder Endpunkt listet denselben generischen „400 Bad Request“ ohne Details auf Fix: Lesen Sie die Fehlerpfade jedes Handlers. Dokumentieren Sie die spezifischen Fehlercodes und Meldungen, die zurückgegeben werden. Unterschiedliche Validierungsfehler sollten unterschiedliche Beispielantworten zeigen.
5. Veraltete generierte Dokumente
Symptom: Spezifikation wurde einmal generiert und nie aktualisiert, als sich der Code änderte
Fix: Generieren Sie in einen bekannten Pfad (docs/openapi.yaml). Fügen Sie einen CI-Check hinzu, der neu generiert und gegen die eingecheckte Spezifikation diffed. Wenn sie abweichen, schlägt der Build fehl.
6. Fehlende Paginierungsdokumentation
Symptom: Listen-Endpunkte werden ohne Query-Parameter-Schemata für Paginierung dokumentiert
Fix: Wenn der Handler page, limit, cursor, offset oder ähnliche Parameter unterstützt, dokumentieren Sie sie mit Standardwerten und Maximalwerten.
7. Undokumentierte Datei-Uploads
Symptom: Multipart/form-data-Endpunkte werden als JSON dokumentiert
Fix: Erkennen Sie multer, formidable, busboy oder framework-native Dateiverarbeitung. Verwenden Sie den multipart/form-data-Content-Type mit korrektem Binär-Schema.
Qualitäts-Checkliste
[ ] Jeder Route-Handler in der Codebasis hat eine entsprechende OpenAPI-Operation
[ ] Pfadparameter stimmen zwischen Code und Spezifikation überein (keine :id vs {userId}-Fehlanpassungen)
[ ] Request-Body-Schemata decken alle erforderlichen und optionalen Felder ab
[ ] Response-Schemata stimmen mit der tatsächlichen JSON-Struktur überein (durch Lesen des Handler-Rückgabewerts verifiziert)
[ ] Authentifizierungsanforderungen stimmen mit der Middleware-Kettenanalyse überein
[ ] Rate-Limit-Informationen dokumentiert, wo Rate-Limiting-Middleware existiert
[ ] Fehlerantworten aus tatsächlichen Throw/Return-Anweisungen in Handlern katalogisiert
[ ] Curl-Beispiele werden erfolgreich gegen eine laufende Instanz ausgeführt
[ ] TypeScript-Typen kompilieren ohne Fehler
[ ] Keine x-inferred-Schemata undokumentiert gelassen (jedes markierte hat ein TODO für ordnungsgemäße Validierung)
[ ] Paginierungsparameter mit Standardwerten und Maximumwerten dokumentiert
[ ] Datei-Upload-Endpunkte verwenden multipart/form-data-Content-Type
[ ] OpenAPI-Spezifikation wird mit spectral oder swagger-cli lint validiert
[ ] Generierte Spezifikation wird für CI-Diffing in einem bekannten Pfad eingecheckt
Ausgabe-Artefakte
docs/openapi.yaml– Vollständige OpenAPI 3.0/3.1-Spezifikationdocs/api-types.d.ts– TypeScript-Typdefinitionen für alle Request/Response-Formendocs/api-examples.sh– Ausführbare curl-Beispiele für jeden Endpunktdocs/api-coverage.md– Bericht, der dokumentierte und undokumentierte Routen auflistet
Validierung
# Die generierte OpenAPI-Spezifikation linten
npx @stoplight/spectral-cli lint docs/openapi.yaml
# Spezifikationsstruktur validieren
npx swagger-cli validate docs/openapi.yaml
# TypeScript-Client generieren, um zu prüfen, ob die Typen kompilieren
npx openapi-typescript docs/openapi.yaml -o /tmp/api-check.d.ts
tsc --noEmit /tmp/api-check.d.ts
# Gegen die zuletzt eingecheckte Spezifikation differ (CI-Check)
diff <(cat docs/openapi.yaml) <(npx tsx scripts/generate-api-docs.ts --stdout) && echo "Spezifikation aktuell" || echo "Spezifikation veraltet"
Abdeckung: OpenAPI-Generierung | TypeScript-Typ-Extraktion | Curl-Beispiel-Erstellung | Auth-Dokumentation | Rate-Limit-Dokumentation | Fehlercode-Katalogisierung
Verwenden mit: api-architect (Design zuerst, danach dokumentieren) | openapi-spec-writer (manuelles Authoring) | test-automation-expert (Vertragstests gegen generierte Spezifikation)