Interoperabilità tra versioni client e server

7

Domanda simile: Come gestisci versioning in un progetto multi-lato?

Poiché la domanda di cui sopra è stata posta quasi 4 anni fa, mi chiedevo se fossero emerse nuove idee.

-

Abbiamo una situazione in cui sviluppiamo una piattaforma che avrà più istanze. Ad esempio:

In generale, tutte le istanze dovrebbero avere un ciclo di vita della versione strettamente sincronizzato, ma a volte potremmo volere avere un'istanza con la versione ad accesso anticipato destinata ai test.

Oltre a quanto sopra, avremo app per Android / iOS che si collegheranno a qualche istanza (l'utente deve selezionare quale). È importante notare che tutte le istanze operano su un database diverso, nessuna replica dovrebbe esistere tra ognuna di queste.

Il problema:

Una volta apportate le modifiche sul lato server, pubblicheremo la nuova versione della versione server e client.

Per i server , dovrebbe essere semplice poiché controlliamo quale versione è installata su quale istanza.

Per i clienti , non appena rilasciamo una nuova versione dell'app client, gli utenti possono estrarla dal rispettivo store e installarla, ma cosa succede quando usano effettivamente l'istanza che sta ancora eseguendo il vecchia versione del server? O quando il client non è in grado di aggiornare a causa della versione obsoleta di Android / iOS?

Qualche idea su come gestirlo?

Un pensiero che ho avuto è stato quello di fornire un endpoint /version.json in modo che l'app client possa ottenere la versione del server e scegliere come operare. Ma questo, imho, potrebbe portare rapidamente a un massiccio gonfiore / duplicazione del codice. Cosa ne pensi?

    
posta Jovan Perovic 24.08.2018 - 17:03
fonte

3 risposte

4

Proxy personalizzati e stub, che gestiscono l'adattamento della versione

Quindi, per fare in modo che funzioni bene, devi eseguire la versione dell'API. Ogni versione diversa dell'API che può vedere un'azione nel campo richiede una nuova versione.

Quindi creo una libreria (per qualsiasi lingua che accederà a questa API WS), che è il binding della lingua madre per tale API.

note - alcune lingue forniscono strumenti per creare automaticamente proxy e stub. Sebbene possano essere utilizzati internamente, non dovrebbero essere pubblicati direttamente per questo scopo (libreria client / stub per l'API del servizio).

L'API della libreria pubblicata deve sempre corrispondere alla versione ULTIMA del protocollo (il più fedelmente possibile, molto raramente potrebbe essere necessario generalizzare leggermente per adattarsi a versioni diverse).

Questa API proxy / stub, all'inizio della comunicazione, è in grado di stabilire la versione del peer con cui sta parlando e di eseguire il downgrade delle comunicazioni in base alle esigenze.

note - come tipicamente , per la maggior parte dei metodi, questo strato proxy / stub può essere piuttosto semplice, ma fornisce un livello in cui avviene la traduzione di tutti i protocolli.

Quindi, tutto il resto del codice server / client (di nuovo, in qualunque linguaggio di programmazione) - è appena scritto sull'API della libreria - che corrisponde alla versione più recente (al momento in cui il codice client / server è scritto) del protocollo.

Ho usato questo approccio su più progetti, con C ++, python, C # .net e javascript.

    
risposta data 24.08.2018 - 18:09
fonte
4

Concentrati sull'assicurare che i messaggi passati tra diverse versioni del protocollo possano essere compresi.

In generale, questo significa

  • Non aggiungi mai un nuovo campo obbligatorio a un messaggio
  • È possibile aggiungere campi facoltativi, ma nel protocollo
  • è necessario specificare un valore predefinito
  • I campi non vengono mai riutilizzati per un nuovo significato.
  • I consumatori devono ignorare i campi facoltativi non riconosciuti

Quindi se mi invii un messaggio con campi facoltativi di cui non conosco, lo ignoro. Se nel tuo messaggio manca un campo opzionale che mi aspetto, allora posso usare il protocollo dei messaggi per determinare quale valore predefinito dovrebbe essere usato.

Un riferimento che copre abbastanza bene questo è Versioning in un sistema di approvvigionamento di eventi di Greg Young.

Quando XML era in ascesa, la semantica Must ignorante era un argomento comune. Vedi David Orchard.

Potresti anche dare un'occhiata a Eric Wilde: Modelli per la robusta estensibilità .

    
risposta data 24.08.2018 - 17:38
fonte
4

Version your server API . Il client non ha bisogno di sapere qual è la versione corrente dell'API, il client deve sapere quale versione dell'API supporta le tue istanze.

Ci sono due opzioni generali per richiedere una risorsa con versione. Puoi includere la versione richiesta dall'URI o includerla in un'intestazione HTTP:

Esempio di controllo delle versioni nell'URI:

GET http://instance{x}.myplatform.com/v1/{resource}

Esempio di controllo delle versioni nelle intestazioni:

GET http://instance{x}.myplatform.com/{resource}
X-API-Version: v1

GET http://instance{x}.myplatform.com/{resource}
Accept: application/json+v2

Naturalmente, potresti anche scegliere di supportare entrambi i metodi. Si noti che sto solo includendo il numero di versione principale. Se stai aderendo al versioning semantico , il cliente deve solo essere a conoscenza del numero di versione principale che sta utilizzando (poiché cambia solo quando interruzioni di compatibilità all'indietro). È possibile scegliere di fornire l'intero numero di versione se lo si desidera, ma potrebbe aumentare la logica che è necessario gestire sul lato server per determinare quale codice deve essere eseguito. Il client sa a quale versione dell'API è stato sviluppato, quindi dovrebbe essere in grado di rendere tali informazioni disponibili al momento della richiesta.

Questo significa che è necessario avere versioni precedenti della tua API in giro, ma ha senso dal momento che hai versioni precedenti del tuo client in circolazione senza controllo su quando vengono aggiornate. Puoi monitorare l'utilizzo della tua API in base alla versione e prendere la decisione di staccare la spina e rimuoverla completamente ogni volta che scende al di sotto di qualche soglia.

Il tuo approccio /version.json potrebbe essere utile se le tue istanze API possono mai trovarsi in uno stato in cui hanno versioni principali diverse che supportano. In tal caso, prima che l'utente selezioni l'istanza a cui desiderano connettersi, è necessario interrogarli e determinare se supportano la versione dell'API richiesta dal client. In caso contrario, il client non vorrebbe connettersi a loro.

    
risposta data 24.08.2018 - 17:55
fonte

Leggi altre domande sui tag