Le API RESTful tendono a incoraggiare modelli di dominio anemici?

32

Sto lavorando a un progetto in cui stiamo cercando di applicare sia la progettazione basata sul dominio sia REST a un'architettura orientata ai servizi. Non ci preoccupiamo della conformità al 100% del REST; sarebbe probabilmente meglio dire che stiamo cercando di costruire API HTTP orientate alle risorse (~ Level 2 di Richardson's REST modello di maturità). Tuttavia, stiamo cercando di evitare l'uso in stile RPC delle richieste HTTP, ovvero tentiamo di implementare i nostri verbi HTTP in base a RFC2616 anziché utilizzare POST per fare IsPostalAddressValid(...) , ad esempio.

Tuttavia, un'enfasi su questo sembra essere a spese del nostro tentativo di applicare la progettazione basata sul dominio. Con solo GET , POST , PUT , DELETE e pochi altri metodi usati di rado, tendiamo a creare servizi CRUDdy e i servizi CRUDdy tendono ad avere modelli di dominio anemici.

POST : riceve i dati, li convalida e li invia ai dati. GET : recupera i dati, li restituisce. Nessuna logica di business reale lì. Usiamo anche messaggi (eventi) tra i servizi e mi sembra che la maggior parte della logica aziendale finisca per essere costruita intorno a questo.

REST e DDD sono tesi a un certo livello? (O sto fraintendendo qualcosa qui? Stiamo forse facendo qualcosa di sbagliato?) È possibile costruire un modello di dominio strong in un'architettura orientata ai servizi evitando le chiamate HTTP in stile RPC?

    
posta Kazark 14.01.2014 - 22:07
fonte

7 risposte

36

La prima legge di Martin Fowler sui sistemi distribuiti: "Non distribuire i tuoi oggetti!" Le interfacce remote dovrebbero essere interfacce a grana grossa e interne a grana fine. Spesso il modello di dominio ricco si applica solo all'interno di un contesto limitato .

L'API REST separa due contesti diversi entrambi con i propri modelli interni. I contesti comunicano attraverso un'interfaccia a grana grossa (API REST) utilizzando oggetti "anemici" (DTO).

Nel tuo caso sembra che tu stia cercando di diffondere un contesto su un confine che è l'API REST. Questo può portare all'interfaccia remota a grana fine o al modello anemico. A seconda del progetto, potrebbe essere o meno un problema.

    
risposta data 15.01.2014 - 07:18
fonte
9

Il POST è stato deliberatamente progettato per essere "intenzionalmente vago;" il risultato di un POST è specifico dell'implementazione. Cosa ti impedisce di fare ciò che fanno Twitter e altri progettisti API e definire ogni metodo POST nella parte non CRUD della tua API in base ai tuoi specifici requisiti? POST è il verbo catchall. Usalo quando nessuno degli altri verbi si adatta bene all'operazione che vuoi eseguire.

Per dirla in un altro modo, la tua domanda potrebbe essere posta ugualmente come "Gli oggetti 'intelligenti' incoraggiano la progettazione in stile RPC?" Anche Martin Fowler (che ha coniato il termine "Modello di dominio anemico") ammette che i DTO nudi hanno alcuni vantaggi:

Putting behavior into the domain objects should not contradict the solid approach of using layering to separate domain logic from such things as persistence and presentation responsibilities. The logic that should be in a domain object is domain logic - validations, calculations, business rules - whatever you like to call it.

Per quanto riguarda il modello di maturità Richardson , puoi raggiungere il livello 3 senza mai preoccuparti dei "Modelli di dominio anemico". Ricorda, non trasferirai mai il comportamento al browser (a meno che tu non abbia intenzione di iniettare JavaScript nei tuoi modelli).

REST riguarda principalmente l'indipendenza della macchina; implementare il modello REST nella misura in cui si desidera che gli endpoint rappresentino le risorse e che i consumer della propria API possano accedere e mantenere facilmente tali risorse in un modo standard. Se ciò sembra anemico, allora così sia.

Vedi anche
Ho bisogno di altri verbi

    
risposta data 14.01.2014 - 22:17
fonte
4

L'API REST è solo un tipo di livello di presentazione. Non ha nulla a che fare con il modello di dominio.

La domanda che hai postato deriva dalla tua confusione sul fatto che in qualche modo devi adattarti l'un l'altro. Non lo fai.

Associa il tuo modello di dominio all'API REST nello stesso modo in cui esegui il mapping del tuo modello di dominio a un RDBMS tramite ORM: deve esserci questo livello di mappatura.

Dominio ← ORM → RDBMS
Dominio ← Mappatura REST → API REST

    
risposta data 17.05.2014 - 15:09
fonte
3

IMHO Non penso che tendano a incoraggiare modelli di dominio anemici (ADM), ma richiedono un certo tempo per riflettere.

Prima di tutto, penso che la caratteristica principale degli ADM sia che hanno poco o nessun comportamento in loro. Questo non vuol dire che il sistema non abbia alcun comportamento, solo che di solito è in una sorta di classe di servizio (vedi link ).

E ovviamente se il comportamento non esiste nell'ADM, allora cosa fa? La risposta ovviamente sono i dati. E quindi come fa questa mappa all'API REST? Presumibilmente, le mappe dei dati si riferiscono al contenuto della risorsa e il comportamento si associa ai verbi HTTP.

Quindi hai tutto ciò che ti serve per costruire un modello di dominio ricco, devi solo essere in grado di vedere come i verbi HTTP mappano alle operazioni di dominio sui dati e quindi mettere quelle operazioni nelle stesse classi che incapsulano i tuoi dati .

Penso che le persone tendono a imbattersi in problemi è che hanno difficoltà a vedere come i verbi HTTP mappano al loro comportamento di dominio quando il comportamento è al di là del semplice CRUD, cioè quando ci sono effetti collaterali in altre parti del dominio oltre la risorsa che viene modificata dalla richiesta HTTP. Un modo per risolvere questo problema è con gli eventi di dominio ( link ).

    
risposta data 15.01.2014 - 07:47
fonte
3

Questo articolo è abbastanza correlato all'argomento e credo che risponda alle tue domanda.

Un concetto fondamentale che penso risponda alla tua domanda molto bene, è riassunto nel seguente paragrafo dall'articolo citato:

"È molto importante distinguere tra le risorse nell'API REST e le entità di dominio in una progettazione basata sul dominio. La progettazione basata sul dominio si applica al lato dell'implementazione delle cose (inclusa l'implementazione dell'API) mentre le risorse nell'API REST guidano la progettazione e il contratto dell'API La selezione delle risorse API non deve dipendere dai dettagli di implementazione del dominio sottostante. "

    
risposta data 14.11.2017 - 17:09
fonte
1

Diverse implementazioni ragionevolmente riuscite che ho visto / costruite rispondono alla domanda nel modo in cui mescolano il verbo + metafora del nome usando metodi "business friendly" a grana grossa che agiscono sulle entità.

Quindi, al posto del (%) metodo / servizio (condannato) getName() , esponi getPerson() , passando in cose come identificatore-tipo / ID, restituendo l'intera entità Person .

Poiché i comportamenti dell'entità Person in un tale contesto non possono essere trasmessi adeguatamente (né forse dovrebbero essere in un contesto incentrato sui dati come questo), è perfettamente ragionevole definire un modello di dati (rispetto all'Oggetto) per la richiesta / coppie di risposte del / i servizio / i.

I servizi e gli stessi verbi definiti aggiungeranno alcuni comportamenti, controlli e persino regole di transizione dello stato per le entità. Ad esempio, ci sarebbe una logica specifica del dominio per ciò che accade nella chiamata al servizio transferPerson() , ma l'interfaccia stessa definirà solo gli input / output entità / dati senza definire i comportamenti interni THEIR.

Non sono d'accordo con autori che direbbero, ad esempio, che un'implementazione di verbo transfer appartiene alla classe Person o è associata a un servizio incentrato sulla persona. Infatti, il metodo di trasferimento per un Person e le sue opzioni (in questo semplice esempio) sarebbe meglio definito da un Carrier , in cui Person potrebbe non avere alcuna conoscenza di quale trasferimento i metodi sono disponibili o come avviene il trasferimento (chissà come funzionano i motori a reazione)

Questo rende l'entità Person anemica? Io non la penso così

Ci può / dovrebbe essere logico su cose specifiche della Persona che sono interne a Person come il loro stato di salute, che non dovrebbe essere definito da una classe esterna.

Tuttavia, a seconda dei casi d'uso, è del tutto accettabile che una classe di entità non abbia comportamenti importanti / rilevanti in alcuni sistemi, come un servizio di assegnazione dei posti in un sistema di trasporto. Un tale sistema può ben implementare servizi basati su REST che trattano le istanze di Person e gli identificatori associati, ma non definiscono mai / implementano i loro comportamenti interni.

    
risposta data 20.03.2014 - 23:36
fonte
0

Il tuo problema è che stai cercando di inserire il tuo modello nel set di base dei verbi, usando il POST il più possibile?

Non è necessario - So che per molte persone REST significa POST, GET, PUT e DELETE, ma http rfc dice:

The set of common methods for HTTP/1.1 is defined below. Although this set can be expanded, additional methods cannot be assumed to share the same semantics for separately extended clients and servers.

E i sistemi come SMTP usano lo stesso stile di metodi basati sui verbi ma con un set completamente diverso.

Quindi, non c'è alcun motivo per cui devi usarli, puoi usare qualunque insieme di verbi che ti piacciono (anche se, in realtà, scoprirai che puoi fare tutto ciò di cui hai bisogno nella Base 4 con un po 'di pensiero). La cosa che distingue REST dagli altri meccanismi è il suo modo stateless e coerente di implementare questi verbi. Non dovresti provare a implementare il sistema di passaggio dei messaggi tra i livelli poiché in pratica non stai facendo REST, ma stai facendo invece un meccanismo di trasmissione dei messaggi, RPC o message-queue che perderà sicuramente i vantaggi di REST (ovvero il semplicità che lo fa funzionare molto bene su una connessione http).

Se si desidera un protocollo di messaggistica complesso e completo, è necessario crearlo (se è possibile farlo tramite il Web, esiste un motivo per cui REST è così popolare), ma in ogni caso cercare di attenersi alla progettazione architettonica di REST.

    
risposta data 15.01.2014 - 14:21
fonte

Leggi altre domande sui tag