WCF / SOA - Perché dovrei creare oggetti parametro per richieste semplici


12

La nostra azienda sta avviando un'iniziativa SOA piuttosto ampia. Stiamo facendo un sacco di cose giuste: c'è una buona comunicazione; denaro per strumenti ove appropriato; e abbiamo portato alcune buone competenze per aiutarci con la transizione.

Stiamo cercando di sviluppare standard che possiamo seguire come gruppo e uno degli standard proposti mi dà un po 'fastidio:

Abbiamo standardizzato il modello in cui ogni operazione accetta un oggetto richiesta e restituisce un oggetto risposta.

Mi rendo conto che questo è più o meno un approccio standard per molte persone, ma mi chiedo perché dovrei preoccuparmi? (Non sono così bravo con la saggezza ricevuta, ho bisogno del perché).

La maggior parte dei servizi che fornirò sono semplici recupero di metadati organizzativi. Ad esempio, trova la politica di sicurezza per un determinato utente. Ciò richiede un ID utente e nient'altro. Lo standard mi dice che dovrei racchiudere questa richiesta in un oggetto e avvolgere la politica restituita in un oggetto risposta.

Il mio disagio è amplificato da uno sguardo al WSDL generato dai nostri contratti. WCF genera automaticamente messaggi di richiesta e risposta e racchiude anche l'oggetto richiesta / risposta.

Comprendo perfettamente che se si effettua una richiesta complessa, è garantito un oggetto di input complesso. Questo è ciò che faresti anche se i servizi non fossero coinvolti.

La mia domanda è: perché dovrei avvolgere automaticamente le richieste e le risposte quando:

  • Rende i servizi semplici meno espressivi
  • Lo faresti comunque per un servizio complesso
  • WCF crea comunque un messaggio di richiesta / risposta

Ho trovato i seguenti argomenti a favore di questo approccio:

Supporta il controllo delle versioni consentendo di inserire parametri opzionali nell'oggetto richiesta.

In passato, ho fatto un bel po 'di COM e lo considererei quasi un anti-pattern per il versioning. Per alcune cose, suppongo che sarebbe d'aiuto, ma mi aspetto che dove sarebbe d'aiuto, hai già un oggetto parametro comunque.

Consente a dati e comportamenti comuni di essere isolati in una classe base

Questo ha un certo peso con me.

Allontana le persone da un comportamento in stile RPC e verso un comportamento di messaggistica

L'ho letto sul sito di Microsoft e l'ho sentito dal nostro guru, ma non ho ancora un'idea chiara di cosa significhino o perché sia ​​prezioso. Le interfacce dall'aspetto naturale fanno sì che le persone tendano a dimenticare di chiamare un servizio remoto?

Sto cercando di riformattare le firme di forse 300 metodi, quindi questa è una quantità non banale di dolore. Sono un grande fan della coerenza delle implementazioni, quindi sono disposto ad assumermi il dolore, aiuterà solo a sapere che alla fine ne varrà la pena.

Risposte:


3

Penso che il versioning sia probabilmente l'argomento migliore. Quando hai un contratto di operazione esistente come

int GetPersons(int countryId);

che si desidera migliorare, ad esempio da un altro filtro in seguito

int GetPersons(int countryId, int age);

Dovresti scrivere un nuovo contratto di operazione e con un nuovo nome poiché deve essere univoco. Oppure manterresti il ​​nome e pubblicheresti un nuovo v2 del tuo servizio con il vecchio v1 ancora in circolazione per compatibilità con le versioni precedenti.

Se si avvolge il parametro in un oggetto, è sempre possibile estenderlo con i parametri predefiniti / facoltativi e tutti i client esistenti non saranno interessati quando si riutilizza lo stesso contratto di operazione.

Tuttavia, esorto anche a nominare i tuoi oggetti in modo appropriato. Anche se avvolge semplicemente un int, se inizi con IntMessagequalcosa di simile non stai facendo un favore estendendolo. Dovresti nominarlo, ad es. PersonFilterFin dall'inizio, il che significa che devi pensare un po 'a ciò che questa chiamata di servizio dovrebbe aspettarsi come parametro semanticamente e quindi cosa dovrebbe fare. Forse (e forse è molto vago) che aiuterà a sviluppare i giusti servizi e a mantenere un'API di dimensioni decenti.

Consente a dati e comportamenti comuni di essere isolati in una classe base

È qualcosa di cui essere cauti. I contratti su ereditarietà e dati non vanno così bene insieme. Funziona, ma dovrai specificare tutti i sottotipi noti del contratto che potrebbero andare oltre il filo, altrimenti il ​​serializzatore del contratto dati non si lamenta di tipi sconosciuti.

Ma quello che potresti fare (ma probabilmente non dovrei, sono ancora indeciso su questo) è riutilizzare gli stessi messaggi tra servizi diversi. Se si inseriscono i contratti di dati in una dll separata, è possibile condividerli tra client e servizio e non è necessario convertirli tra tipi quando si chiamano servizi diversi che prevedono sostanzialmente lo stesso messaggio. Ad esempio, si crea un PersonFilter e lo si invia a un servizio per ottenere un elenco di filtri di persone e quindi a un altro servizio e avere gli stessi oggetti sul client. Non riesco a trovare un buon esempio nel mondo reale per questo e il pericolo è sempre che un'estensione dei contratti di dati non sia abbastanza generale per tutti i servizi che utilizzano questo contratto.

Nel complesso, a parte il controllo delle versioni, non riesco davvero a trovare il motivo killer per farlo in quel modo.


Penso al motivo per cui prendo il
Andy Davis il

(scusate, l'interfaccia dei commenti mi sta dando dolore) Grazie per aver risposto. Penso che il motivo per cui prendo l'argomento versioning con un tale granello di sale è che se hai aggiunto un nuovo argomento probabilmente hai cambiato la semantica. Se (come nel tuo esempio) hai appena aggiunto un'età, probabilmente la semantica era per la ricerca e all'inizio avevi un "oggetto di ricerca".
Andy Davis,

Ora considera il mio esempio di politica di sicurezza. Forse decidiamo che per fornire correttamente una politica di sicurezza, dobbiamo conoscere non solo l'utente, ma la struttura in cui stanno lavorando. Questo è molto più che aggiungere un argomento, abbiamo cambiato la semantica della chiamata. Supponendo che siamo in qualche modo in grado di fornire queste informazioni per un chiamante della versione precedente, penso che abbia più senso la versione del contratto di servizio. Quindi l'implementazione per la vecchia versione può essere isolata e non si finisce per mescolare la vecchia semantica con la nuova.
Andy Davis,

0

Le note di Martin Fowler sull'oggetto di trasferimento dei dati sono appropriate qui, credo.

Quando lavori con un'interfaccia remota, come Remote Facade (388), ogni chiamata è costosa. Di conseguenza è necessario ridurre il numero di chiamate e ciò significa che è necessario trasferire più dati con ogni chiamata. Un modo per farlo è usare molti parametri. Tuttavia, questo è spesso difficile da programmare, anzi, è spesso impossibile con linguaggi come Java che restituiscono un solo valore.

La soluzione è creare un oggetto di trasferimento dati in grado di contenere tutti i dati per la chiamata. Deve essere serializzabile per attraversare la connessione. Di solito un assemblatore viene utilizzato sul lato server per trasferire dati tra il DTO e qualsiasi oggetto di dominio.

Lo stesso potrebbe valere per le richieste. Per quanto riguarda RPC, e perché è male:

Le interfacce dall'aspetto naturale fanno sì che le persone tendano a dimenticare di chiamare un servizio remoto?

Penso che sia vero, ma non il motivo principale. Un altro motivo per evitare RPC è che può incoraggiare clienti e servizi strettamente accoppiati.


Grazie per il contributo, ma non credo che la discussione DTO sia così rilevante. È lo stesso numero di chiamate e, se si osserva WSDL, tutto viene automaticamente impacchettato in un oggetto richiesta e risposta. La convenzione riguarda la semantica visibile , vale a dire che la gente dovrebbe pensare a questa come una richiesta e risposta invece di una chiamata di metodo remota.
Andy Davis,

Ti andrebbe di approfondire gli RPC che incoraggiano clienti e servizi strettamente accoppiati? Non riesco a vedere che questo influisca sul servizio. Per il cliente, non vedo davvero come cambia qualcosa. In entrambi i casi, ho il client in possesso di un proxy che descrive una serie di operazioni fornite da un servizio. Chi implementa effettivamente l'altro lato del servizio non è in ogni caso l'attività del cliente.
Andy Davis,
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.