Protocol-first design
Cos'è Protocol-first
Protocol-first è un approccio in cui il contratto di interazione tra i componenti (servizi, clienti, partner esterni) viene progettato e stabilito prima dell'implementazione. Codice, storage, infrastruttura e documentazione sono sottoposti a contratto e generati automaticamente, non viceversa.
A differenza dì code-first ", dove l'API è solo un sottoprodotto del codice, Protocol-first rende il protocollo un artefatto primario: possiede i concetti di dominio, i modelli di dati, gli stati, gli errori, la semantica di idampotenza, la SLO/SLI e persino la politica di versione.
Perché è necessario
Coerenza e prevedibilità delle interfacce a livello aziendale.
Onboarding rapido (generazione automatica SDK/stub/client, unico errore e codici).
Evoluzione affidabile (compatibilità degli schemi, test contrattuali, regole di versione chiare).
Focus sul prodotto: discutere di comportamento, SLA e UX di integrazione prima di scrivere il codice.
Automazione: CI/CD raccoglie manufatti (client, stub server, validatori) da una sola fonte di verità.
Sicurezza e compilazione: diritti, occultamento PII, regole di reticenza sono fissati nel contratto.
Motore di avvicinamento
1. Fonte unica di verità (SSOT) - Specifiche leggibili:
REST: OpenAPI/JSON Schema.
Gli eventi e lo streaming, l'Avro/JSON Schema.
RPC: Protobuf (gRPC), Thrift, Smithy.
GraphQL SDL + direttive/regole.
2. Accordi pre-implementazione: glossario di dominio, codici di errore, semantica di idempotenza, deduplicazione, retrai, deduplicazione.
3. Generazione automatica: client/server, tipi, SDK, contratti-test, moki, raccolte Postman, Terraform/OpenAPI Gateway-config.
4. Governance: Linter/Policy (naming, paginazione, filtri, errori), review attraverso l'API-Gild, change-advisory per le versioni maggiori.
5. Compatibilità: controllo rigoroso dei diffusi «additive-only», versioning semantico, test canary/consumer-driven.
6. Osservabilità a livello di contratto: ID correlati, modelli di errore, budget di ritardo sono scritti nel protocollo.
Come appare il processo (scheletro)
1. Iniziazione: breef → user journeys → API/Protocol PRD (risorse/metodi/eventi, SLA/SLO, errori, limiti).
2. Modellazione: bozza di specifica (OpenAPI/AsyncAPI/Proto) + schemi di dati, dizionario di termini.
3. Contratti e X integrazione: esempi di carico utile, contratti di errore, mappe statali, regole di versioning.
4. Corno e governance: linter/standard, discussione invarianti di dominio, lock-in MGC (contratto minimo di garanzia).
5. Generazione automatica di manufatti: SDK, branco, fisture di prova, stub dell'infrastruttura (Gateways, IAM scopes).
6. Implementazione e test di contratto: il fornitore e i consumatori vengono sottoposti a test di compatibilità in CI.
7. Osservabilità e SLO: tracciabilità per correlation-id, errato catalog, budget retrae/timeout.
8. Release e evoluzione: additive-first, deprecation policy, canary, A/B capability flags.
Protocolli e stili di interazione
REST/HTTP
Standard: modello di risorse, 'GET/POST/PATCH/DELETE', paginazione (cursor), filtri, ordinamento.
Campi e schemi: JSON Schema, formati («data-time», «uuid»), invarianti (regex/enum/min-max).
Errore: formato unico ('type', 'code', 'title', 'detail', 'trace _ id'), mapping su stack HTTP.
Controllo delle modifiche: ETag/If-Match, chiavi idropotenti POST, semantiche espresse 409/422.
gRPC/RPC
Protobuf: numerazione stabile dei tag, «optional», divieto di riutilizzare i campi remoti.
Deadlins e priorità nel contratto; States stabili (OK, INVALID _ ARGEMENT, FAILED _ PRECISION, etc.).
Streaming - Specifica l'ordine dei messaggi, backpressure, trailer finali.
Event-driven (Kafka/NATS/SNS/SQS)
AsyncAPI: argomenti/canali, chiavi di partitura, accordi di deduplicazione, retenza, semantica "vs" almeno una volta ".
Evento kernel e arricchimento: separa payload minimo e estensioni versione'event _ type '/' schema _ variante '.
Idampotenza: «event _ id», «producer _ id», policy per i retrai e la deduplicazione.
GraphQL
SDL come contratto, direttive per il deprecato, limiti di profondità e complessità, contratto di errore (errore codes/estensioni).
Integrazione con i principi architettonici
Inverse Pyramid/Critical Path First: seleziona MGC (minimo obbligatorio) nella specifica, con «? include = »/capabilities.
Paved Roads - Set di modelli di specifiche finite (payment, KYC, audit, search, files) + Linter.
API Gateways & Service Mesh: regole basate sul contratto (rate-limits, auth scopes, retries, circuiti-breakers).
Versioning e evoluzione
Semantic Versioning:- Minor = solo campi/canali additivi.
- Maggiore = Modifiche distruttive (eliminazione, rinominazione, modifica della semantica).
- Deprecation Policy: finestre di supporto, intestazioni Sunset, eventi-notifica.
- Consumer-Driven Contracts (CDC) - Verifica che l'API corrente soddisfi i consumatori specifici.
- Elenco degli schemi: registro (Schema Registry/Artifact Registry) con cronologia e regole di compatibilità (BACKWARD/FORWARD/FULL).
Protezione e compliance
Autenticazione/autorizzazione come parte del contratto (OAuth2/OIDC scopes, mTLS, JWT clims).
PII/PCI: maschera, formati di tornitura, campi con modalità speciali di conservazione/TTL.
Criteri di verifica: attributi obbligatori («attore», «subject», «action», «occurred _ at», «trace _ id»).
Limiti: rate limit headers, quote, dimensioni dei messaggi, deadline.
Osservabilità contrattuale
Correlation/Richiest-ID: obbligatorio nella specifica.
Errore Catalog: un elenco fisso di codici e SLA da eliminare.
SLI/SLO: p50/p95 latency, percentuale di risposte di successo, percentuale di eventi compatibili, percentuale di ripetizioni idipotenti.
Test e qualità
Contract test (fornitore ↔ consumatore), schema differf in CI, generazione di MCU.
Golden sample: esempi di riferimento di richieste/risposte, ficsture per e2e.
Chaos/latency injection - Verifica timeout/retrai, degrado delle estensioni mantenendo MGC.
Modelli di dominio approssimativi
Pagamento (REST+ eventi)
«POST/payments» (chiave Idempotent) → «201 Created» con «payment _ id», «status = authorized».
Evento dì payment ". authorized. v1` (ядро): `{ payment_id, amount, currency, method, occurred_at }`.
Estensione dì payment ". enriched. v1 ': rischio-scansione, geo, device-fingerprint.
Errori: '422' (convalida), '402' (payment richired), '409' (duplicata).
SLA autorizzazione 800ms p95; evento kernel ≤ 2s lag p95.
KYC (gRPC + code)
RPC `StartVerification(user_id)` → `operation_id`.
Eventi di avanzamento nel topico'kyc. status. v1` (`PENDING` → `APPROVED/REJECTED`).
Il contratto prevede campi PII, conservazione, occultamento, codici causali di guasto.
Controllo (Event-only)
`audit. recorded. v1` (ядро): `actor`, `subject`, `action`, `occurred_at`, `trace_id`.
Arricchimento: IP, device, geo - singolo evento/flusso, non blocca il kernel.
Strumenti e automazione (pila approssimativa)
Спеки: OpenAPI/AsyncAPI/Protobuf/Avro/GraphQL SDL.
Линтеры: Spectral, OpenAPI Diff, Buf (protobuf), Confluent SR compatibility checks.
Генерация: OpenAPI Generator, Buf/Protoc, GraphQL Codegen, AsyncAPI Generator.
Gaitway: Kong/Apigee/Azure/GCP GW, Avvoy.
Тесты: Pact/CDC, Dredd, Schemathesis, Hoverfly, MockServer.
Registro: Git-directory di diagrammi + Schema Registry/Artifact Registry.
Documentazione: Redocly/Stoplight/Swagger-UI/GraphiQL/Explorer.
Anti-pattern
Code-first by accent: «prima MVP sui controller», specifica post-fattura, corrispondenza di documentazione e comportamento.
Swagger-wash: OpenAPI formale senza regole reali (errori, limiti, SLA, versioni).
Livello di compatibilità - Eliminato il campo/modificato il tipo senza la versione maggiore; riutilizzo dei tag protobuf.
Risposta «spessa» senza paginazione/filtri; Non c'è idipotenza.
Security fuori contratto: auth/Scopes sono descritti in wiki, ma non in specifiche.
Relazione con l'organizzazione del processo
API Wild: gestori di standard, cambiamento, formazione.
Design Docs: per ogni API - PRD, ADR (soluzioni), SLA, matrice di rischio.
Cambio Management: processo RFC, release note, gate migratorie, deprecation-timeline.
Paved Road & Templates - Generatori di ossatura del servizio da specifiche (scheletro handler, convalida, loging).
Assegno fogli
Prima dell'avvio
- Ci sono PRD e glossario di dominio.
- Lo stile (REST/gRPC/Event/GraphQL) e il formato degli schemi sono selezionati.
- Definiti MGC, errori, SLA/SLO, regole di idempotenza.
In fase di sviluppo
- Le specifiche passano da linter e review.
- La generazione automatica SDK/stub/ficstur è configurata.
- Il contratto-test (CDC) è incluso nell'ICI; schema-differf blocca le modifiche incompatibili.
Prima del lancio
- Documentazione per gli integratori con esempi e codici di errore.
- Osservabilità contrattuale: correlation-id, error catalog, dashboard SLI.
- Criteri di versionalità e deprecation annunciati.
FAQ
In cosa è diverso Protocol-first dall'API-first?
Spesso i termini vengono usati come sinonimi. In questo articolo, sotto Protocol-first, sottolineiamo la rigidità del contratto e la copertura di tutti gli stili (SLA, sicurezza e osservabilità).
Potrebbe rallentare lo sviluppo?
La partenza può essere un po'più lunga, ma poi vinciamo su integrazioni, stabilità e velocità di sviluppo parallelo (auto-generazione, SDK stabili).
Cosa fare con gli esperimenti rapidi?
Utilizzate le versioni «bozze» di diagrammi (draft), feature flags e arenili, ma non ignorate i liner e le regole di compatibilità di base.
Totale
Protocol-first design rende il contratto il centro dell'architettura: negoziamo il comportamento, fissiamo gli schemi, automatizziamo la generazione e i test, evolviamo in modo additivo. Il risultato è l'integrazione prevedibile, l'elevata velocità di sviluppo e la resistenza dei sistemi ai cambiamenti di scala e di comando.