modello per condividere oggetti tra API e applicazione


9

Sto avendo seri dubbi sulla progettazione della mia applicazione Web.

Volevo separare la logica aziendale dall'interfaccia, quindi ho creato un'API Web che gestisce tutte le richieste al database.

È un'API Web ASP.NET con framework Entity e un'unità di lavoro e un modello di repository generico. Finora è andato tutto bene.

PROBLEMA

Dove ho bisogno di aiuto è non riesco a capire un modo efficiente di condividere oggetti tra l'API e l'applicazione.

Non voglio serializzare direttamente l'oggetto entità, ho pensato che sarebbe stata una cattiva pratica perché se il modello di entità cambia, potrei finire con la serializzazione di oggetti di grandi dimensioni senza motivo.

Come è implementato ora

Poiché la mia interfaccia è l'applicazione Web ASP.NET in C # e la mia API è in C #, ho creato una libreria comune con la definizione di tutte le mie classi che voglio condividere tra di loro.

So che la soluzione non funzionerà quando svilupperò un'app Android, dovrò creare di nuovo le mie lezioni in Java, ma questo non è il mio problema più grande.

Il problema è che mi sento come se stessi convertendo sempre i miei oggetti.

ESEMPIO

Ecco un esempio del mio flusso di lavoro:

Comincio con un modello con tutti gli oggetti e le annotazioni dei dati per il mio modulo, quindi l'utente POST quel modello su un controller.

Nel controller devo convertire questo modello in una classe nella mia libreria comune quindi inviare quell'oggetto alla mia API.

Quindi un controller nella mia API cattura la chiamata e converte quell'oggetto in un oggetto entità per aggiornare il database.

Quindi ho 3 lezioni

  1. Il modello per la vista con tutte le annotazioni dei dati per la convalida (client)
  2. Le classi di librerie comuni per condividere gli oggetti (DLL)
  3. Le classi di entità (API)

Ho la sensazione di fare qualcosa di veramente sbagliato. C'è qualcosa di più elegante? Vorrei assicurarmi di avere una buona soluzione a questo problema prima che il progetto diventi troppo grande.


Se la mia domanda non è chiara, non esitare a fare domande.
Marc,

Per me non è chiaro quale architettura hai implementato (forse è la dicitura .net che mi confonde) - è un'architettura a 3 livelli: client, server, db?
Andy,

Sì, ho un'applicazione Web che utilizza un'API Web. L'API è quella con la logica aziendale con il database.
Marc,

Risposte:


12

So che sembra che tu stia convertendo oggetti avanti e indietro continuamente tra i tuoi oggetti di database, i tuoi oggetti di trasferimento dati, i tuoi oggetti client con logica di validazione e così via, ma direi che no, non stai facendo nulla di male .

Ognuno di questi oggetti può rappresentare la stessa unità di informazione, ma hanno responsabilità molto diverse. L'oggetto database è la tua interfaccia di comunicazione con il database e deve essere mantenuto a livello di database poiché potrebbe contenere o meno annotazioni di metadati del database e / o dettagli non necessari sull'implementazione del database in esso.

Il tuo oggetto di trasferimento dati è l'interfaccia di comunicazione con i tuoi consumatori API. Questi dovrebbero essere il più puliti possibile per facilitare il consumo da diverse lingue / piattaforme. Ciò potrebbe imporre alcune restrizioni sull'aspetto e sul comportamento di questi in base ai consumatori API che desideri supportare.

I tuoi oggetti client con la logica di validazione non fanno davvero parte del tuo progetto API, fanno parte del tuo progetto consumer. Questi non possono essere gli stessi degli oggetti di trasferimento dei dati in questo caso poiché si stanno aggiungendo ulteriori logiche specifiche del client (in questo caso gli attributi di convalida) su cui il server non sa nulla (e non si dovrebbe sapere nulla!) contare questi oggetti come parte dell'API, perché in realtà non lo sono. Sono altamente specifici per le applicazioni consumer e alcune applicazioni che consumano la tua API potrebbero non aver nemmeno bisogno di creare questi oggetti e potrebbero sopravvivere solo sui tuoi oggetti di trasferimento dati. Ad esempio, se non avessi alcuna necessità di convalida non avresti bisogno di un ulteriore livello di oggetti completamente identici ai tuoi oggetti di trasferimento dati.

Per me, sembra che ciascuno dei tre tipi di oggetto sia associato molto bene a una singola responsabilità che è la codifica pulita e la buona pratica. Purtroppo, codice pulito e buone pratiche a volte significano che stai scrivendo un sacco di codice extra e saltando attraverso cerchi extra "solo perché". E durante la codifica, potrebbe essere difficile apprezzare il valore che questo ti sta dando, ma non appena rilasci l'applicazione e inizi a supportarla o aggiungendo nuove funzionalità per la prossima versione, probabilmente inizierai ad apprezzare che hai impiegato del tempo per separare queste preoccupazioni correttamente in primo luogo. (Per non parlare del fatto che tu '

Odio anche scrivere codice di conversione tra diversi tipi di oggetti come questo, ma la mia soluzione è in genere una delle seguenti:

  • Usa una libreria che fa la maggior parte della conversione di oggetti pesante per te - per esempio, se usi C # puoi usare la fantastica libreria di AutoMapper ( http://automapper.org/ ). Credo che ci siano un paio di altre librerie come questa, ma AutoMapper è la più potente che abbia mai visto finora.
  • Se non riesci a trovare una libreria che ti aiuti nelle conversioni di oggetti, scrivi una serie di metodi di utilità per la conversione tra di loro. Questo potrebbe far schifo, ma a lungo andare ne vale la pena, scrivi il metodo di conversione la prima volta che devi convertire qualcosa - non aspettare.

Grazie per le tue spiegazioni ma trovo ancora difficile capire qualcosa. Non capisco perché il layer per il trasferimento dei dati non abbia alcuna validazione? Cosa succede se dimentico alcune convalide per la mia prossima app mobile? Almeno non verrà convalidato quando chiamo l'API invece di fare un'eccezione nel mio modello di database. Non sono sicuro di aver capito.
Marc,

1
Non sto dicendo che non dovresti convalidare a livello di API. Ad essere onesti, è il posto più importante in cui convalidare. La convalida nella tua app è solo una "bella funzione" per aiutare i tuoi utenti a non commettere errori, la convalida degli oggetti di trasferimento dei dati serve a tenere fuori i dati dannosi ed errati. Dato che questi sono diversi casi di utilizzo tuttavia, potrebbe essere necessario utilizzare diversi framework di validazione (si dovrà utilizzare diversi framework di convalida se la vostra applicazione e la vostra API non è scritto nella stessa lingua) e si può validare le cose leggermente diverse ad ogni livello (Cont nel prossimo commento)
wasatz

1
Quindi dovresti validare i tuoi oggetti di trasferimento dati. Ma dovresti anche assicurarti che il modo in cui li convalidi non introduca accidentalmente dipendenze da qualsiasi altro framework . E, naturalmente, come ho detto prima, non puoi davvero essere sicuro che i tuoi oggetti di trasferimento dati siano stati validati o che siano stati validati dallo stesso framework - quindi devi "validare due volte".
wasatz

2
Principalmente, dovresti provare a visualizzare l'applicazione e l'API come due applicazioni completamente diverse e separate. È possibile che vengano sviluppati contemporaneamente e che potrebbero trovarsi nello stesso progetto di Visual Studio Solution / Eclipse. Ma sono davvero due programmi completamente separati. Quando lavori nella tua applicazione, prova a "dimenticare" che sei quello che ha creato l'API e usala come faresti con una normale API di terze parti. In questo modo avrai maggiori possibilità di vedere come si sentiranno gli altri quando usano la tua API e correggere le parti peggiori all'inizio.
wasatz

1
E lo stesso vale ovviamente quando lavori sul tuo progetto API, prova a immaginare di scrivere un servizio che molti sviluppatori di terze parti useranno. Cerca di non pensare troppo alla tua attuale applicazione, ma piuttosto di concentrarti maggiormente su "quali servizi sto fornendo" e supponendo che tutti coloro che usano la tua API (incluso te stesso) siano persone malvagie che stanno cercando di uccidere il tuo server e ti fanno cancellare l'intero database.
wasatz,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.