Sto provando a progettare un'applicazione con un dominio aziendale complesso e un requisito per supportare un'API REST (non rigorosamente REST, ma orientata alle risorse). Ho qualche problema a trovare un modo per esporre il modello di dominio in un modo orientato alle risorse.
In DDD, i client di un modello di dominio devono passare attraverso il livello procedurale "Application Services" per accedere a qualsiasi funzionalità aziendale, implementata da entità e servizi di dominio. Ad esempio, esiste un servizio di applicazione con due metodi per aggiornare un'entità utente:
userService.ChangeName(name);
userService.ChangeEmail(email);
L'API di questo servizio di applicazione espone comandi (verbi, procedure), non stati.
Ma se abbiamo anche bisogno di fornire un'API RESTful per la stessa applicazione, allora c'è un modello di risorse utente, che assomiglia a questo:
{
name:"name",
email:"[email protected]"
}
L'API orientata alle risorse espone stato , non comandi . Ciò solleva le seguenti preoccupazioni:
-
ogni operazione di aggiornamento rispetto a un'API REST può eseguire il mapping a una o più chiamate di procedure del servizio applicazioni, a seconda delle proprietà che vengono aggiornate sul modello risorsa
-
ogni operazione di aggiornamento sembra atomica al client REST API, ma non è implementata in questo modo. Ogni chiamata al servizio dell'applicazione è progettata come una transazione separata. L'aggiornamento di un campo su un modello risorsa potrebbe modificare le regole di convalida per altri campi. Pertanto, è necessario convalidare tutti i campi del modello di risorsa insieme per garantire che tutte le potenziali chiamate al Servizio applicazioni siano valide prima di iniziare a produrle. Convalidare un insieme di comandi contemporaneamente è molto meno banale che eseguirne uno alla volta. Come possiamo farlo su un client che non sa nemmeno che esistono comandi individuali?
-
chiamare i metodi del servizio di applicazione in ordine diverso potrebbe avere un effetto diverso, mentre l'API REST fa sembrare che non ci siano differenze (all'interno di una risorsa)
Potrei trovare altri problemi simili, ma fondamentalmente sono tutti causati dalla stessa cosa. Dopo ogni chiamata a un servizio applicativo, lo stato del sistema cambia. Regole di ciò che è un cambiamento valido, l'insieme di azioni che un'entità può eseguire il prossimo cambiamento. Un'API orientata alle risorse tenta di rendere tutto simile a un'operazione atomica. Ma la complessità di superare questa lacuna deve andare da qualche parte, e sembra enorme.
Inoltre, se l'interfaccia utente è più orientata ai comandi, che spesso è il caso, allora dovremo mappare tra comandi e risorse sul lato client e poi di nuovo sul lato API.
Domande:
- Tutta questa complessità dovrebbe essere gestita da un layer di mappatura REST-to-AppService (spesso)?
- O mi manca qualcosa nella mia comprensione di DDD / REST?
- Potrebbe REST essere semplicemente non pratico per esporre la funzionalità dei modelli di dominio su un certo grado (abbastanza basso) di complessità?