REST has a uniform interface constraint which is the following in a very zipped opinion based format.
- You have to use standards like HTTP, URI, MIME, etc...
- You have to use hyperlinks.
- You have to use RDF vocabs to annotate data and hyperlinks with semantics.
- You do all of these to decouple the client from the implementation details of the service.
DDD with CQRS (or without it) is very similar as far as I understand.
- By CQRS you define an interface to interact with the domain model. This interface consists of commands an queries classes.
- By DDD you define domain events to decouple the domain model from the persistence details.
- By DDD you have one ubiquitous language per bounded context which expresses the semantics.
- You do all of these to completely decouple the domain model from the outside world.
Is it possible to map the REST uniform interface to the domain interface defined by commands and queries and domain events? (So the REST service code would be generated automatically.)
Is it possible to map the linked data semantics to the ubiquitous languages? (So you wouldn't need to define very similar terms, just find and reuse existing vocabs.)
Please add a very simple mapping example to your answer, why yes or why not!
I don't think this is possible. There is a term which I believe describes this problem, it is called ontology alignment.
In this case have have at least 3 ontologies:
- the ubiquitous language (UL) of the domain model
- the application specific vocab (ASO) of the REST service
- the linked open data vocabs (LODO) which the application specific vocab uses
So we have at least 2 alignments:
- the UL : ASO alignment
- the ASO : LODO alignment
Our problem is related to the UL : ASO alignment, so let's talk about these ontologies.
The UL is object oriented, because we are talking about DDD and domain model. So most of the domain objects entities
, value objects
are real objects and not data structures. The non-object-oriented part of it are the DTOs like command+domainEvent
, query+result
and error
on the interface of the domain model.
In contrast the ASO is strictly procedural, we manipulate the resources (data structures) using a set of standard methods (procedures) on them.
So from my aspect we are talking about 2 very different things and we got the following options:
- make the ASO more object oriented -> RPC
- make the UL less object oriented -> anaemic domain model
So from my point of view we can do the following things:
- we can automatically map entities to resources and commands to operations by CRUD, for example the HydraBundle does this with active records (we can do just the same with DDD and without CQRS)
we can manually map commands to operations by a complex domain model
- the operation
POST transaction {...}
can result a SendMoneyCommand{...}
- the operation
GET orders/123/total
can result a OrderTotalQuery{...}
we cannot map entities to resources by a complex domain model, because we have to define new resources to describe a new service or a new entity method, for example
- the operation
POST transaction {...}
can result account.sendMoney(anotherAccount, ...)
- the operation
GET orders/123/total
can result in an SQL query on a read database without ever touching a single entity
I think it is not possible to do this kind of ontology alignment between DDD+CQRS and REST, but I am not an expert of this topic. What I think we can do is creating an application specific vocab with resource classes, properties and operations and map the operations to the commands/queries and the properties to the command/query properties.
You have posed some interesting questions here.
To start with I do not quite agree with
By DDD you define domain events to decouple the domain model from the
persistence details.
I think you might be confusing Event Sourcing ES with DDD, ES can be used with DDD but its very much optional in fact you should give it a lot of thought before choosing it as your persistence mechanism.
Now to the bulk of your question, of whether REST and DDD get along if yes how ?
My take on it, yes they do get along, however generally you do not want to expose your domain model via a REST interface, you want to build a abstraction over it and then expose that.
You can refer to this answer here, for a little more detail.
However i cannot recommend enough the Implementing Domain-Driven Design book, Chapter 14 Application deals with your concern to a fair degree.
I could not have explained it more thoroughly than the book and hence referring you there :)