Modifiche alle API

Buone pratiche di versionamento API, per i chiamanti

8 min di lettura

Il versionamento API è la pratica di mantenere funzionante un vecchio contratto dopo averlo cambiato, così i chiamanti possono muoversi secondo il proprio calendario invece del vostro. Quella frase contiene le due decisioni che contano: cosa conta come cambiare il contratto, e per quanto tempo continua a funzionare quello vecchio. Dove vive il numero di versione, argomento della maggior parte dei dibattiti sul versionamento, è la meno importante delle tre e la più facile da azzeccare.

Quando si dovrebbe versionare un’API?

Versionate un’API solo quando un cambiamento romperebbe un chiamante corretto. I cambiamenti additivi, nuovi campi, nuovi endpoint, nuovi parametri opzionali, non hanno bisogno di una versione; i chiamanti scritti contro il vecchio contratto continuano a funzionare e la nuova capacità è semplicemente lì. Un cambiamento che rompe qualcosa ne ha bisogno, perché l’alternativa è che un chiamante lo scopra da un errore. Versionare ogni rilascio, inclusi quelli additivi, insegna ai chiamanti che le versioni sono rumore, e smettono di leggere gli avvisi che contano.

Il test pratico è lo stesso dell’articolo sui cambiamenti che rompono qualcosa: se un chiamante che dipendeva solo dal comportamento documentato deve cambiare qualcosa per continuare a funzionare, il cambiamento ha bisogno di una versione. Se no, rilasciatelo sotto la versione attuale e scrivete una voce di changelog.

Quale schema di versionamento API si dovrebbe usare?

Usate lo schema che i vostri chiamanti possono vedere e impostare più facilmente, che per la maggior parte delle API pubbliche è una versione nel percorso URL o un header di versione datato. I quattro schemi comuni differiscono meno in capacità che in cosa chiedono al chiamante, e quella è la base giusta per scegliere.

SchemaEsempioCosa deve fare il chiamanteChi lo usa
Percorso URL/v2/invoicesCambiare l’URL quando migraLa maggior parte delle API REST pubbliche
Header di versioneX-GitHub-Api-Version: 2022-11-28Inviare un header, o accettare il defaultGitHub
Versione account datataStripe-Version: 2026-08-26Fissare una data per richiesta o per accountStripe
Parametro query/invoices?version=2Aggiungere un parametroAPI più vecchie; oggi raramente scelto
Media typeAccept: application/vnd.example.v2+jsonNegoziare tipi di contenutoPuristi; pochi chiamanti lo padroneggiano

Percorso URL è il più visibile e il meno flessibile. Ogni chiamante può vedere in quale versione si trova leggendo una riga di log, e un salto di versione è un cerca-e-sostituisci. Il costo: l’intera superficie si sposta in una volta, non potete cambiare il contratto di un singolo endpoint senza coniare una nuova versione per tutti, così le versioni di percorso tendono a essere rare e grandi.

Header di versione mantiene stabili gli URL e lascia che il server scelga un default per i chiamanti che non inviano nulla, così come funziona il versionamento dell’API REST di GitHub: una versione nominata per data in X-GitHub-Api-Version, con la versione supportata più vecchia come default così i chiamanti non versionati non si rompono. Il costo: la versione è invisibile in un URL e facile da dimenticare in un nuovo client.

Versione account datata è lo schema header più un’aggiunta: la versione è memorizzata contro l’account, così ogni richiesta la ottiene senza inviare nulla. Il versionamento API di Stripe fissa ogni account alla versione con cui è stato creato e lascia che una richiesta lo sovrascriva con Stripe-Version. Questo è lo schema più amichevole per il chiamante e quello che richiede più lavoro da gestire, perché il server deve tradurre tra ogni versione supportata e quella attuale.

Parametro query e media type funzionano entrambi e falliscono entrambi il test di visibilità in modo diverso: un parametro query si perde facilmente costruendo un URL, e una versione media type è invisibile per quasi qualsiasi strumento con cui un chiamante debugga. Lo schema di Stripe a date è l’esempio più noto dell’approccio per data, e come Stripe versiona la sua API lo ripercorre.

Come si fa il versionamento API in pratica?

In pratica una versione è un insieme nominato di comportamenti, e il server mappa ogni richiesta su uno di essi. I passi sono gli stessi qualunque sia lo schema che porta il nome.

  1. Nominate le versioni per data o per intero, non per versione semantica. Un’API web non è un pacchetto. I chiamanti non possono fissare una versione minor di un URL, così v2 o 2026-08-26 dice tutto ciò di cui un chiamante ha bisogno, e il versionamento semantico implica una promessa di compatibilità che lo schema non può mantenere.
  2. Tenete la versione fuori dai percorsi di codice che non se ne preoccupano. Una versione dovrebbe selezionare uno strato di traduzione al margine, non biforcare la logica di business. Due copie complete della codebase sono come una versione finisce non mantenuta.
  3. Date a ogni versione un default e un documento. I chiamanti che non inviano versione ricevono la più vecchia supportata, mai la più nuova, così un client non fissato non si rompe il giorno del rilascio. Ogni versione ha una pagina che dice cosa è cambiato rispetto alla precedente.
  4. Fissate una finestra di supporto e pubblicatela. Le linee guida di Google sul versionamento, AIP-185, chiedono un periodo di transizione ragionevole e ben comunicato e raccomandano 180 giorni persino per le funzionalità beta. Scegliete una finestra, scrivetela, e applicatela senza rinegoziare per versione.
  5. Ritirate le versioni come ritirate gli endpoint. Una versione oltre la sua finestra riceve lo stesso trattamento di qualsiasi API deprecata: un annuncio, un header Sunset (RFC 8594) su ogni risposta, un promemoria a metà strada ai chiamanti rimasti, e una data di rimozione che tiene.

Cosa sono v1 e v2 in un’API REST?

v1 e v2 sono nomi per due contratti che lo stesso server supporta contemporaneamente. Un v2 esiste perché qualcosa in v1 non poteva essere cambiato senza rompere i suoi chiamanti, così il cambiamento è andato in un nuovo contratto e quello vecchio ha continuato a funzionare. I numeri non implicano che v2 sia completo o che v1 sia morto; entrambe le cose sono vere solo se la documentazione lo dice. Un v3 che appare ogni trimestre è un segno che si stanno versionando cambiamenti additivi, o che il contratto non è mai stato progettato per assorbire il cambiamento. gRPC risolve lo stesso problema diversamente: cambiamenti API gRPC e Protobuf copre il versionamento tramite il nome del package in un file .proto invece di un percorso URL, e un formato di wire dove rinominare un campo è gratis ma rinumerarlo è un breaking change che nessun chiamante REST riconoscerebbe come rischioso.

Cosa dovrebbe annunciare un cambio di versione?

Un cambio di versione dovrebbe annunciare cosa rompe, chi interessa, come migrare, e per quanto tempo continua a funzionare la versione precedente. La voce ha la stessa forma di qualsiasi altra voce di cambiamento che rompe qualcosa, più una riga con la finestra di supporto. Eccone una per un’API versionata per header:

La versione API 2026-11-01 è disponibile. La versione 2025-06-15 è supportata fino al 1° novembre 2027. Nuovo in 2026-11-01: GET /invoices restituisce amount in unità minime come intero invece che come stringa decimale, e il campo deprecato customer_name viene rimosso a favore dell’oggetto customer. Interessa i chiamanti su 2025-06-15 che parsano amount come stringa, che è il default per client non fissati creati prima di giugno 2025. Migrazione: parsate amount come intero e leggete il nome da customer.name. Fissate X-Api-Version: 2026-11-01 quando siete pronti. Nulla cambia per i chiamanti che non fissano versione.

L’ultima frase è quella che permette alla maggior parte delle lettrici di smettere di leggere, e appartiene a ogni annuncio di versione. La pagina esempi di changelog include voci di API che versionano così, e la differenza tra le buone e il resto sta soprattutto in quell’ultima frase.

Chi viene informato quando cambia una versione?

Tutti sulla versione vecchia, individualmente, e il changelog per tutti gli altri. Un cambio di versione è l’unico caso in cui “abbiamo pubblicato qualcosa a riguardo” garantisce di perdere esattamente i chiamanti che contano: quelli che hanno fissato una versione due anni fa e non hanno letto una nota di rilascio da allora. I dati di utilizzo rispondono chi sono; l’avviso deve raggiungerli dove sta il loro codice, negli header di risposta e in un messaggio alla proprietaria dell’account.

Nel ciclo che eseguiamo, la voce che annuncia una versione viene redatta dalla pull request che la rilascia, revisionata da una persona, e pubblicata su feed e widget, dove un client versionato può leggerla come JSON. Chi ha chiesto il cambiamento, o ha segnalato il bug che risolve, con un feedback dal widget diventato un issue GitHub che la pull request chiude, viene informato su quell’issue non appena la voce viene pubblicata. Il meccanismo è lo stesso di qualsiasi voce; un salto di versione è solo la voce con la posta più alta.

FAQ

Ogni cambiamento API dovrebbe ottenere una nuova versione? No. Solo i cambiamenti che rompono qualcosa. I cambiamenti additivi si rilasciano sotto la versione attuale con una voce di changelog. Versionare i cambiamenti additivi insegna ai chiamanti a ignorare le versioni.

È meglio il versionamento URL o quello per header? Il versionamento URL è più facile da vedere per i chiamanti e più difficile da far evolvere pezzo per pezzo per voi; quello per header è il contrario. Per un’API pubblica con molti piccoli client, il versionamento URL fallisce meno. Per un’API grande con strato di traduzione, la versione datata per header scala meglio.

Quante versioni dovrebbero essere supportate contemporaneamente? Il meno possibile secondo la vostra finestra di supporto, e mai un numero illimitato. Due o tre versioni concorrenti è normale; più di quello di solito significa che le versioni non vengono ritirate.

Cosa dovrebbero ricevere le richieste non versionate? La versione supportata più vecchia, così i client esistenti non fissati continuano a funzionare, con un header di risposta che dice loro quale versione hanno ricevuto.


Le affermazioni tecniche di questo articolo non sono state verificate in modo indipendente. Se qualcosa non è corretto, faccelo sapere e lo correggeremo.

Correlati su changeloop: Documentazione per sviluppatori, Esempi di changelog

changeloop
Il team che costruisce un changelog che chiude il cerchio. I tuoi utenti chiedono, il tuo team rilascia, chi ha chiesto lo viene a sapere.