Mi scuso in anticipo per la lunghezza di questa domanda; richiede qualche spiegazione. Cercherò di renderlo il più chiaro possibile.
Sto sviluppando e gestendo un'app mobile (Xamarin, F #) che comunica con un'API Web (ASP.NET Core, F #). L'API lato server esiste solo per comunicare con l'app e eseguire operazioni di database e altre richieste HTTP in base alle esigenze. Il modello di dominio, per così dire, è più o meno esattamente lo stesso nell'app e nell'API. Ad esempio, sia l'app che l'API hanno un concetto di CardId
con le stesse nozioni di ciò che costituisce esattamente un ID di carta valido.
Poiché le app non possono essere aggiornate istantaneamente, devo eseguire la versione dell'API in modo che gli utenti di versioni di app obsolete possano ancora utilizzare il servizio. Attualmente l'app e il server comunicano serializzando / deserializzando semplici tipi di DTO (inviati come payload JSON su HTTP) definiti in un assembly comune a cui fanno riferimento sia l'app che l'API. Ad esempio, un ID della carta è rappresentato come una semplice stringa. I tipi in questo assembly condiviso sono versionati e l'app e l'API convertono tra questi tipi e i tipi corrispondenti che usano internamente.
-
Dal lato app, l'app converte tra le rappresentazioni interne (definite negli assembly dell'app) e l'ultima versione di questi tipi (poiché l'app deve solo funzionare con una singola versione API).
-
Dal punto di vista dell'API è simile, ma l'API contiene convertitori per tutte le versioni dei tipi condivisi, poiché deve supportare anche le versioni precedenti.
Tutto ciò significa che qualsiasi concetto / tipo condiviso tra l'app e il server richiede almeno 3 tipi (per una singola versione): uno nell'app, uno nell'API e uno nella assembly condiviso da serializzare / deserializzare - così come 2-4 convertitori (1-2 ciascuno nell'API / API, a seconda che sia necessario ricevere / inviare i tipi o entrambi). Questo è molto robusto poiché disaccoppia la rappresentazione interna (e la logica che lavora su di essi) dalla comunicazione tra app e server, ma è molto dannoso. Inoltre, mi porta spesso a interrompere la logica dall'app: ad esempio, l'ID di una scheda nell'app viene modellato come una semplice stringa e l'API esegue la convalida e può restituire un codice di errore che indica "ID carta non valido".
Ora, quello che voglio fare è semplicemente condividere gli oggetti tra client e server. Se potessero in qualche modo condividere la memoria (assurdo, ma spiega il mio punto), ciò semplificherebbe molto le cose. Poiché sia il client che il server utilizzano la stessa piattaforma / lingua (.NET / F #), e questo è improbabile che cambi mai (in tal caso, si potrebbe sempre tornare alla soluzione attuale), ho preso in considerazione il crollo di tutte e tre le versioni di un digita (app, API e condivisa) in un singolo tipo (sempre versione, ovviamente) e semplicemente serializza / deserializza. Ad esempio, utilizzando una sorta di serializzazione binaria (non ho esperienza con questo).
Ciò garantisce che il server e l'app parlino realmente la stessa lingua e che i concetti di parità siano trattati allo stesso modo. Ad esempio, posso condividere oggetti complessi con garanzie su alcuni invarianti per costruzione (come il CardID sopra menzionato) e sapere che tutto l'invariante vale ancora una volta che l'ho deserializzato dall'altra parte, perché è lo stesso identico oggetto. Potrei quindi anche sbarazzarmi di diversi controlli lato server ed errori come "ID carta non valido" perché l'app non potrebbe mai costruire e inviare un ID carta non valido in primo luogo.
Significa anche che in tutta la mia app e API, ci sarebbero riferimenti a una versione specifica di oggetti, ma non penso che sarebbe peggio mantenere la soluzione corrente.
Tuttavia, non riesco a scuotere la sensazione che mi sarei in qualche modo sparato al piede, o che il controllo delle versioni sarebbe più difficile e fragile, anche se non riesco a individuare il motivo per cui mi sento così (forse si sente solo più robusto con oggetti dedicati che uso per la serializzazione / deserializzazione e conversione da / verso l'interno, ma mi sto ancora affidando alla serializzazione / deserializzazione di questi oggetti DTO, quindi perché non andare fino in fondo?). La domanda è quindi:
Alla luce della spiegazione di cui sopra, si condividono gli oggetti tra client e server utilizzando, ad es. la serializzazione binaria è una buona opzione, o ho perso alcuni chiari problemi con questo approccio? Ho forse perso un'altra opzione migliore interamente?