Come rendere le tue API REST compatibili con le versioni precedenti

Il Representational State Transfer, comunemente noto come REST, è uno stile architettonico, un insieme di vincoli utilizzati per implementare servizi senza stato eseguiti su HTTP. Un'API RESTful è quella conforme ai vincoli REST. Puoi creare API RESTful utilizzando molti linguaggi di programmazione diversi.

Mantenere la compatibilità con le versioni precedenti tra le diverse versioni della tua API è della massima importanza per garantire che la tua API rimanga compatibile con tutti i client che la utilizzano. Questo articolo presenta una discussione su come mantenere la compatibilità con le versioni precedenti nelle API RESTful.

Esempio di compatibilità API

Supponi di avere un'API in produzione che viene utilizzata da client diversi. Ora, se desideri aggiungere più funzionalità all'API, dovresti assicurarti che i client che utilizzano la vecchia API saranno in grado di utilizzare la nuova API o quella vecchia. In altre parole, dovresti assicurarti che la funzionalità esistente dell'API rimanga intatta mentre viene aggiunta la nuova funzionalità.

Un'API è retrocompatibile se un client (un programma scritto per utilizzare l'API) che può funzionare con una versione dell'API può funzionare allo stesso modo con le versioni future dell'API. In altre parole, un'API è retrocompatibile tra le versioni se i client dovrebbero essere in grado di lavorare con una nuova versione dell'API senza problemi.

Capiamolo con un esempio. Supponi di avere un metodo API denominato GetOrders come mostrato nello snippet di codice di seguito.

[HttpGet]

[Route ("GetOrders")]

 public IActionResult GetOrders (int customerId, int orderId = 0)

 {

   var result = _orderService.GetOrdersForCustomer (

                 customerId, orderId);

   return Ok (risultato);

 }

Il metodo di azione GetOrders accetta un ID cliente e un ID ordine come parametri. Notare che il secondo parametro, orderID, è facoltativo. Di seguito viene fornito il metodo privato GetOrdersForCustomer.

elenco privato GetOrdersForCustomer (int customerId, int orderId)

{

   // Scrivi qui il codice per restituire uno o più record dell'ordine

}

Il metodo GetOrdersForCustomer restituisce tutti gli ordini di un cliente se l'orderId passato ad esso come parametro è 0. Se orderId è diverso da zero, restituisce un ordine relativo al cliente identificato dal customerId passato come argomento.

Poiché il secondo parametro del metodo di azione GetOrders è facoltativo, puoi semplicemente passare customerId. Ora, se modifichi il secondo parametro del metodo di azione GetOrders per renderlo obbligatorio, i vecchi client dell'API non saranno più in grado di utilizzare l'API.  

[HttpGet]

[Route ("GetOrders")]

 public IActionResult GetOrders (int customerId, int orderId)

 {

   var result = _orderService.GetOrdersForCustomer

                 (customerId, orderId);

   return Ok (risultato);

 }

Ed è esattamente così che puoi rompere la compatibilità della tua API! La sezione che segue discute le best practice che possono essere adottate per rendere la tua API compatibile con le versioni precedenti.

Suggerimenti per la compatibilità API

Ora che sappiamo qual è il problema, come progettiamo le nostre API nel modo consigliato? Come ci assicuriamo che la nostra API RESTful sia compatibile con le versioni precedenti? Questa sezione elenca alcune delle migliori pratiche che possono essere seguite a questo proposito. 

Assicurati che gli unit test vengano superati

Dovresti avere test scritti che verificheranno se la funzionalità è intatta con una nuova versione dell'API. I test dovrebbero essere scritti in modo tale da non riuscire se ci sono problemi di compatibilità con le versioni precedenti. Idealmente dovresti avere una suite di test per il test delle API che fallirà e avviserà quando ci sono problemi con la compatibilità con le versioni precedenti dell'API. Potresti anche avere una suite di test automatizzata collegata alla pipeline CI / CD che verifica la compatibilità con le versioni precedenti e avvisa quando si verifica una violazione.

Non modificare mai il comportamento dei codici di risposta HTTP

Non dovresti mai modificare il comportamento dei codici di risposta HTTP nella tua API. Se la tua API restituisce 500 quando non riesce a connettersi al database, non dovresti cambiarlo in 200. Allo stesso modo, se stai restituendo HTTP 404 quando si verifica un'eccezione ei tuoi client stanno usando questo e l'oggetto risposta per identificare cosa è andato sbagliato, la modifica di questo metodo API per restituire HTTP 200 interromperà completamente la compatibilità con le versioni precedenti.

Non modificare mai i parametri

Evita di creare una nuova versione dell'API quando apporti solo piccole modifiche, poiché potrebbe essere eccessivo. Un approccio migliore consiste nell'aggiungere parametri ai metodi API per incorporare il nuovo comportamento. Allo stesso modo, non dovresti rimuovere i parametri da un metodo API o modificare un parametro da facoltativo a obbligatorio (o viceversa), poiché queste modifiche interromperanno l'API e i vecchi client o consumatori dell'API non saranno più in grado per lavorare con l'API.

Versione della tua API

Il controllo delle versioni delle API è una buona pratica. Il controllo delle versioni aiuta a rendere la tua API più flessibile e adattabile alle modifiche mantenendo intatta la funzionalità. Ti aiuta anche a gestire meglio le modifiche al codice e ripristinare più facilmente il vecchio codice se il nuovo codice causa problemi. Dovresti avere una versione diversa della tua API RESTful con ogni versione principale.

Sebbene REST non fornisca alcuna guida specifica sul controllo delle versioni dell'API, puoi eseguire la versione dell'API in tre modi diversi: specificando le informazioni sulla versione nell'URI, archiviando le informazioni sulla versione nell'intestazione della richiesta personalizzata e aggiungendo le informazioni sul controllo delle versioni all'HTTP Accept intestazione. Sebbene il controllo delle versioni possa aiutarti a mantenere la tua API, dovresti evitare di provare a mantenere molte versioni dell'API per contrassegnare i rilasci frequenti. Questo diventerà rapidamente macchinoso e controproducente. 

Altre best practice per le API

Non modificare mai l'URL radice di un'API o modificare i parametri della stringa di query esistenti. Qualsiasi informazione aggiuntiva dovrebbe essere aggiunta come parametro facoltativo a un metodo API. Dovresti anche assicurarti che gli elementi facoltativi o obbligatori passati a un'API o restituiti da un'API non vengano mai eliminati.

Le modifiche a un'API RESTful sono inevitabili. Tuttavia, a meno che tu non aderisca alle best practice e assicuri che l'API sia compatibile con le versioni precedenti, le tue modifiche possono interrompere la compatibilità dell'API con i client esistenti. Un'API in produzione e utilizzata da più client deve essere sempre compatibile con le versioni precedenti tra le versioni.