I'm trying to design an application that has a complex business domain and a requirement to support a REST API (not strictly REST, but resource-oriented). I have some trouble coming up with a way to expose domain model in a resource-oriented manner.
In DDD, clients of a domain model need to go through procedural 'Application Services' layer to access any business functionality, implemented by Entities and Domain Services. For example there's an application service with two methods to update a User entity:
userService.ChangeName(name);
userService.ChangeEmail(email);
The API of this Application Service exposes commands (verbs, procedures), not state.
But if we also need to provide a RESTful API for the same application, then there is a User resource model, that looks like this:
{
name:"name",
email:"[email protected]"
}
The resource-oriented API exposes state, not commands. This raises the following concerns:
each update operation against a REST API can map to one or more Application Service procedure call, depending on what properties are being updated on the resource model
each update operation looks like atomic to REST API client, but it is not implemented like that. Each Application Service call is designed as a separate transaction. Updating one field on a resource model could change validation rules for other fields. So we need to validate all resource model fields together to ensure that all potential Application Service calls are valid before we start making them. Validating a set of commands at once is much less trivial that doing one at a time. How do we do that on a client that doesn't even know individual commands exist?
calling Application Service methods in different order might have a different effect, while REST API makes it look like there's no difference (within one resource)
I could come up with more similar issues, but basically they all are caused by the same thing. After each call to an Application Service, state of the system changes. Rules of what is valid change, the set of actions an entity can perform next change. A resource-oriented API tries to makes it all look like an atomic operation. But the complexity of crossing this gap must go somewhere, and it seems huge.
In addition, if the UI is more command-oriented, which often is the case, then we'll have to map between commands and resources on the client side and then back on the API side.
Questions:
- Should all this complexity just be handled by a (thick) REST-to-AppService mapping layer?
- Or am I missing something in my understanding of DDD/REST?
- Could REST simply be not practical for exposing functionality of domain models over a certain (fairly low) degree of complexity?