API linting e analisi statica
1) Perché linter API
API è un contratto tra team e integratori esterni. Linting e analisi statiche:- impediscono modifiche incompatibili e implicite
- unificare gli stati, gli errori, la paginazione, la sicurezza;
- rendono prevedibili le specifiche della macchina e le release;
- riducono i costi con la gelosia e i tempi di onboarding.
Principio: "I contratti vengono controllati automaticamente; Il PR senza linting verde non è magro".
2) Oggetti linting
1. Contratti: SDL, Protobuf/Avro/JSON Schema.
2. Implementazione: REST/grPC, middleware, codici di stato/intestazione.
3. Infrastruttura: intestazioni di protezione, limiti, criteri della cache.
4. Gli artefatti associati sono esempi, raccolte Postman, schemi di errore.
3) Regole di base per HTTP API (profilo consigliato)
3. 1 Notazione e URL
snake _ case nei corpi JSON, kebab-case nei percorsi o kebab-case/'/v1/... 'uniforme.
Le risorse sono multiple: '/v1/payments ', nidificate -- '/v1/wallets/{ id }/communications'.
Identificatori come path-params: '/v1/payments/{ payment _ id} '(tipo: string, formato: uuid).
3. 2 Metodi e stati
«GET» - 200/206; «POST» - 201 (+ «Location»), conflitto - 409; validazione: 422; i limiti sono 429 (+ «Retry-After»).
Non restituire 200 per errori. Richieste condizionali: 304 per If-None-Match.
3. 3 Errori (formato unico)
json
{ "code":"validation_error", "message":"amount must be ≥ 1", "trace_id":"...", "details":[{"field":"amount","reason":"min:1"}] }
Obbligatori: 'code', 'messagge',' trace _ id '; locale - tramite Content-Language.
3. 4 Paginazione/filtri
Cursor-based: `page_size`, `page_token`, ответ: `next_page_token`.
Filtri e ordinamenti - whitelists documentati in parameters.
3. 5 Sicurezza
Schema di sicurezza unitario: OAuth2/OIDC scopes o mTLS; proibire «http» (solo «https»).
Non restituire titoli sensibili, mascherare i token come esempi.
3. 6 Vincoli e quote
Limiti intestazione/corpo: 413/414/431; Documentare il valore massimo consentito.
4) Strumenti e ecosistemi
4. 1 OpenAPI
Spectral (JSON/YAML lint), Redocly linter, oas-differf/openapi-differf (semantic diff), schemathesis/dreedd (controlli in corso).
4. 2 Protobuf/gRPC
buf (lint + breaking check), protolint, generatori SDK; gnostic per l'analisi.
4. 3 GraphQL
graphql-schema-linter, graphql-inspector (breaking).
4. 4 Linter in codice e SAST
ESLint, golangci-lint, Detekt/Ktlint, Pylint/Flake8, Semgrep (modelli API e sicurezza).
5) Esempi di regole: Spectral/Redocly
5. 1 Spectral (esempio "spectrale. 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 (frammento ".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: profilo buf
6. 1 `buf. yaml`
yaml version: v2 modules:
- path: proto lint:
use:
- DEFAULT except:
- PACKAGE_VERSION_SUFFIX # используем v1 в package breaking:
use:
- WIRE_JSON deps: []
Raccomandazioni:
- Non riutilizzare i numeri di campo cancellabili in «riserved».
- Nuovi campi - «optional» o con default; non modificare i tipi/semantiche.
7) Diff semantico e modifiche «spezzanti»
7. 1 HTTP
Esempi breaking:- Modifica del tipo/obbligatorietà del campo
- Eliminazione dello stato/percorso/parametro
- restringimento enum/intervallo;
- Modifica del formato id (uuid → string).
- Aggiunta di campi facoltativi
- Nuovi stati che non influiscono su happy-path (ad esempio, documentato' 422 ')
- estensione enum.
7. 2 gRPC/Protobuf
Rimuove il campo senza «riserved »/cambia il numero - breaking.
Cambia tipo (int32 → string) - breaking.
Aggiunge un nuovo tag come optional - solitamente safe.
8) Relazione tra linting dei contratti e codice
La coerenza è garantita da due flussi:1. Il contratto → codice: generazione SDK/stub server, esempi negativi nei test.
2. Codice → contratto: test di specifica, controllo automatico dello stato/intestazione.
Idee Semgrep:- il divieto dì return 200 'a «error! = nil»;
- obbligatorio «Idempotency-Key» sui percorsi di pagamento write;
- occultamento dei token nei logi.
9) CI/CD pipline (arbitro)
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
Il PR deve cadere se:
- ci sono breaking-diff;
- Regole di base violate (stato/sicurezza/errore)
- Nessun esempio o descrizione dei parametri.
10) Directory delle regole (modello per la tua organizzazione)
Identificatori e tipi
`_id` — `string`, `format: uuid`.
Campi contanti - «string »/« decimale» con scale; valuta - ISO-4217.
Errori
Un unico schema (vedere l'articolo 3. 3), codici: '400/401/403/404/409/422/429/5xx'.
Sempre «trace _ id»; «Retry-After» per 429/503.
Paginazione
Solo cursor; max 'page _ size' è stato documentato.
Sicurezza
Tutte le operazioni sono «security». descritti'scopes '.
Nessun link http:; TLS 1. 2+.
Cache/idampotenza
Для GET — `ETag/Last-Modified`; per write - 'Idempotency-Key' (se applicabile).
Documentazione
«summary», «descrizione», esempi di richieste/risposte (validi).
11) Esempi di controlli automatizzati
11. 1 Verifica intestazioni di protezione obbligatorie (Spectral)
yaml security-headers:
given: "$.paths[][].responses['200'].headers"
then:
function: truthy
11. 2 openapi-differf (pseudo-passo CI)
openapi-diff --fail-on-incompatible base.yaml pr.yaml
11. 3 buf breaking-check
buf breaking --against '.git#branch=main'
12) Osservazione della qualità dei contratti
Metriche: quota di PR con errori di linting, tempo di fisso, numero di tentativi di breaking, «debiti» secondo le regole.
Dashboard - Avanzamento della migrazione verso un diagramma di errori unificato, copertura degli esempi, stabilità delle versioni.
13) Antipattern
La Doc vive separata dal codice di dissincronizzazione. Tenete il contratto vicino al servizio e rilasciate un manufatto versionizzato.
Linter è solo manuale. Ho bisogno di un hard PR-gate.
Esempi casuali (no-deterministic) - Flaconcini nei controlli.
Nessun esempio negativo e nessun codice di errore.
Rielaborare lo schema di errore per ogni servizio.
Ignora i controlli Protobuf breaking (cambiano i tag a occhio).
14) Specificità iGaming/finanza
Caselle - Scala/arrotondamento fisso divieto di float.
Intestazioni obbligatorie «X-Tenant», «X-Region» e «traceparent».
Maniglie di pagamento write: verifica della presenza dì Idempotency-Key "," Retry-After "e dei corretti 409/201 semantici.
I HMAC/mTLS PSP/KYC sono descritti in «securitySchemes»; anti-replay ('X-Timestamp', finestra).
Limitazioni regionali e localizzazione degli errori (Content-Language).
15) Assegno-foglio prod-pronto
- I profili Spectral/Redocly sono disegnati e collegati in pre-commit e PR-gate.
- Diagramma unico di errori e stato - Vengono registrati e verificati.
- openapi-diff/GraphQL Inspiror/buf - Blocca le modifiche breaking.
- Gli esempi di richieste/risposte sono validi; paginazione/filtri documentati.
- SecuritySchemes e scopes sono pieni; Nessun collegamento http.
- Per Protobuf: 'riserved', sui tag remoti; i nuovi campi sono optional.
- Semgrep/Linter di codice abilitati; occultare i segreti nei reparti.
- CI pubblica gli artefatti dei contratti e i rapporti di linting.
- Playbook: come agire con breaking-diffide (rollback, hotfix, notifiche agli integratori).
16) TL; DR
Implementare il linting automatico dei contratti (Spectral/Redocly, buf/GraphQL Inspiror) e il diff semantico, fissare un unico schema di errori/stato/paginazione/sicurezza, collegare i contratti PR-gate e pubblicare i contratti come artefatti. Qualsiasi breaking-diff è un segnale di stop. Per i soldi/pagamenti - regole speciali (Idempotence, Retry-After, HMAC/mTLS).