Linting API und statische Analyse
1) Warum Sie die API linten sollten
API ist ein Vertrag zwischen Teams und externen Integratoren. Linting und statische Analyse:- inkompatible und implizite Änderungen verhindern;
- vereinheitlichen Status, Fehler, Pagination, Sicherheit;
- die Spezifikationen maschinengeprüft und die Freigaben vorhersehbar machen;
- Reduzieren Sie die Kosten für Revue und Onboarding-Zeit.
Grundsatz: "Verträge werden automatisch geprüft; PR ohne Green Linting ist nicht verboten".
2) Linting-Objekte
1. Verträge: OpenAPI/AsyncAPI/GraphQL SDL, Protobuf/Avro/JSON Schema.
2. Implementierung: REST/gRPC-Stifte, Middleware, Statuscodes/Header.
3. Infrastruktur: Sicherheitsüberschriften, Limits, Cache-Richtlinien.
4. Verwandte Artefakte: Beispiele (Examples), Postman-Sammlungen, Fehlerbilder.
3) Grundregeln für die HTTP-API (empfohlenes Profil)
3. 1 Notation und URL
snake_case in JSON-Körpern, kebab-Fall in Pfaden oder einheitlicher kebab-Fall/'/v1/...'.
Ressourcen - Plural: '/v1/payments', verschachtelt - '/v1/wallets/{ id }/transactions'.
IDs als path-params: '/v1/payments/{ payment _ id}'(Typ: string, Format: uuid).
3. 2 Methoden und Status
„GET“ - 200/206; „POST“ - 201 (+ „Standort“), Konflikte - 409; Validierung - 422; Limits sind 429 (+ „Retry-After“).
Geben Sie 200 nicht für Fehler zurück. Bedingte Anfragen - 304 von 'If-None-Match'.
3. 3 Fehler (einheitliches Format)
json
{ "code":"validation_error", "message":"amount must be ≥ 1", "trace_id":"...", "details":[{"field":"amount","reason":"min:1"}] }
Erforderlich: „code“, „message“, „trace _ id“; local - über die „Content-Language“.
3. 4 Pagination/Filter
Cursor-based: `page_size`, `page_token`, ответ: `next_page_token`.
Filter und Sortierung - Whitelists, dokumentiert in 'parameters'.
3. 5 Sicherheit
Einheitliches Sicherheitsschema: OAuth2/OIDC scopes oder mTLS; „http“ verbieten (nur „https“).
Geben Sie keine sensiblen Überschriften zurück, maskieren Sie Token in Beispielen.
3. 6 Einschränkungen und Abmessungen
Header/Body Limits: 413/414/431; die maximal zulässigen Werte dokumentieren.
4) Werkzeuge und Ökosystem
4. 1 OpenAPI
Spectral (JSON/YAML lint), Redocly linter, oas-diff/openapi-diff (semantic diff), schemathesis/dredd (durchgeführte Prüfungen).
4. 2 Protobuf/gRPC
buf (lint + breaking check), protolint, SDK-Generatoren; gnostic für die Analyse.
4. 3 GraphQL
graphql-schema-linter, graphql-inspector (breaking).
4. 4 Code-Linter und SAST
ESLint, golangci-lint, Detekt/Ktlint, Pylint/Flake8, Semgrep (API-Geruchsmuster und Sicherheit).
5) Regelbeispiele: Spectral/Redocly
5. 1 Spectral (Beispiel 'spectral. yaml`)
yaml extends: ["spectral:oas", "spectral:asyncapi"]
rules:
openapi-tags: off info-contact: error no-http: error path-kebab-case:
description: "Paths must be kebab-case"
given: "$.paths[]~"
severity: error then:
function: pattern functionOptions: { match: "^/(?:[a-z0-9]+(?--[a-z0-9]+)/?)+$" }
response-error-schema:
description: "Error responses must use standard schema"
given: "$.paths[][].responses[?(@property >= '400')]"
then:
field: "content.application/json.schema.$ref"
function: truthy id-as-uuid:
given: "$..parameters[?(@.name =~ /.id$/i)]"
then:
field: schema.format function: enumeration functionOptions: { values: ["uuid"] }
5. 2 Redocly (Fragment von '.redocly. yaml`)
yaml apis:
main: openapi.yaml lint:
extends:
- recommended rules:
no-ambiguous-paths: error operation-2xx-only: off operation-success-response:
severity: error where:
subject: response filterInParentKeys: ["200","201","204"]
operation-security-defined: error no-plain-http: error
6) Protobuf/gRPC: buf-Profil
6. 1 `buf. yaml`
yaml version: v2 modules:
- path: proto lint:
use:
- DEFAULT except:
- PACKAGE_VERSION_SUFFIX # используем v1 в package breaking:
use:
- WIRE_JSON deps: []
Empfehlungen:
- Feldnummern nicht überverwenden; gelöscht - in „reserviert“.
- Neue Felder - 'optional' oder mit Standardwerten; keine Änderung der Typen/Semantik.
7) Semantisches Diff und „aufbrechende“ Veränderungen
7. 1 HTTP
Breaking-Beispiele:- Änderung der Art/Verbindlichkeit des Feldes;
- Löschen des Status/der Route/des Parameters;
- enum/Bereichseinengung;
- Ändern des ID-Formats (uuid → string).
- Optionale Felder hinzufügen
- neue Zustände, die den Happy-Path nicht beeinflussen (z. B. dokumentiert durch „422“);
- Erweiterung enum.
7. 2 gRPC/Protobuf
Löschen eines Feldes ohne' reserviert '/Nummernwechsel - Breaking.
Ändern des Typs (int32 → string) - brechen.
Das Hinzufügen eines neuen Tags als optional ist in der Regel sicher.
8) Link Linting Verträge und Code
Die Konsistenz wird durch zwei Threads gewährleistet:1. Vertrag → Code: Generierung von SDK/Server-Stubs, negative Beispiele in Tests.
2. Code → Vertrag: Spezifikationstests, automatische Überprüfung von Status/Titeln.
Semgrep-Ideen:- Verbot von "return 200" bei "error! = nil';;
- obligatorischer „Idempotency-Key“ auf schriftlichen Zahlungswegen;
- Maskieren von Token in Protokollen.
9) CI/CD Pipeline (Referenz)
pre-commit: spectral lint, redocly lint
PR gate: openapi-diff (base..PR), buf breaking-check, graphql-inspector build: schemathesis smoke, unit/integration linters (ESLint/golangci-lint)
release: publish contracts (artifact/broker), sign & tag
PR muss fallen, wenn:
- es gibt ein Breaking-Diff;
- Grundregeln verletzt werden (Status/Sicherheit/Fehler);
- keine Beispiele/Beschreibungen der Parameter.
10) Regelkatalog (Vorlage für Ihre Organisation)
Bezeichner und Typen
`_id` — `string`, `format: uuid`.
Geldfelder - 'string '/' decimal' mit Skala; Währung ist ISO-4217.
Fehler
Einheitliches System (siehe § 3) 3), Codes: „400/401/403/404/409/422/429/5xx“.
Immer 'trace _ id'; 'Retry-After' für 429/503.
Pagination
Nur cursor; max' page _ size' ist dokumentiert.
Sicherheit
Alle Operationen - 'security' block; beschrieben „scopes“.
Keine' http: 'Links; TLS 1. 2+.
Cache/Idempotenz
Для GET — `ETag/Last-Modified`; für Schreiben - 'Idempotency-Key' (falls zutreffend).
Dokumentation
'Zusammenfassung', 'Beschreibung', Beispiele für Anfragen/Antworten (gültig).
11) Beispiele für automatisierte Prüfungen
11. 1 Überprüfung der obligatorischen Sicherheitsüberschriften (Spectral)
yaml security-headers:
given: "$.paths[][].responses['200'].headers"
then:
function: truthy
11. 2 openapi-diff (Pseudo-CI-Schritt)
openapi-diff --fail-on-incompatible base.yaml pr.yaml
11. 3 buf breaking-check
buf breaking --against '.git#branch=main'
12) Beobachtbarkeit der Vertragsqualität
Metriken: PR-Anteil mit Linting-Fehlern, Fix-Zeit, Anzahl der Breaking-Versuche, „Schulden“ nach Regeln.
Dashboards: Migrationsfortschritt zu einem einheitlichen Fehlerschema, Abdeckung mit Beispielen, Versionsstabilität.
13) Antipatterns
„Doc“ lebt getrennt vom Code → nicht synchron. Halten Sie den Vertrag in der Nähe des Dienstes und veröffentlichen Sie das versionierte Artefakt.
Linter nur von Hand. Wir brauchen ein hartes PR-Gate.
Zufällige Beispiele (nicht-deterministisch) sind Flakes in Kontrollen.
Keine negativen Beispiele und Fehlercodes.
Neuerfindung des Fehlerschemas für jeden Dienst.
Protobuf-Breaking-Checks ignorieren (Tags „per Guckloch“ ändern).
14) Spezifität von iGaming/Finanzen
Geldfelder - feste Skala/Rundung; Float-Verbot.
Obligatorische Überschriften „X-Tenant“, „X-Region“ und Trace „traceparent“.
Payment write-pens: Überprüfen Sie, ob 'Idempotency-Key', 'Retry-After' und korrekte 409/201 Semantik vorhanden sind.
PSP/KYC Webhooks: HMAC/mTLS sind in 'securitySchemes' beschrieben; Anti-Replay ('X-Timestamp', Fenster).
Regionale Einschränkungen und Fehlerlokalisierung („Content-Language“).
15) Checkliste Prod-Ready
- Spectral/Redocly Profile sind im Pre-Commit und PR-Gate angelegt und verbunden.
- Einheitliches Fehlerbild und Status - erfasst und geprüft.
- openapi-diff/GraphQL Inspector/buf - Blockieren von Breaking-Änderungen.
- Beispiele für Anfragen/Antworten sind gültig; Paginierung/Filter sind dokumentiert.
- SecuritySchemes und scopes sind voll; Es gibt keine HTTP-Links.
- Für Protobuf: „reserviert“ auf gelöschten Tags; Die neuen Felder sind optional.
- Semgrep/Code Linters enthalten; Verschleierung von Geheimnissen in Protokollen.
- CI veröffentlicht Vertragsartefakte und Linting-Berichte.
- Playbook: Wie es bei einem Breaking-Diffus weitergeht (Rollback, Hotfix, Benachrichtigungen an Integratoren).
16) TL; DR
Implementieren Sie das automatische Linting von Verträgen (Spectral/Redocly, buf/GraphQL Inspector) und das semantische Diff, erfassen Sie ein einheitliches Fehler-/Status-/Paginierungs-/Sicherheitsschema, verbinden Sie das PR-Gate und veröffentlichen Sie Verträge als Artefakte. Jeder Breaking-Diff ist ein Bremslicht. Für Geld/Zahlungen gelten besondere Regeln (Idempotenz, 'Retry-After', HMAC/mTLS).