DDD eXchange - Restful Objects - Dan Haywood
A Brief Guide to RESTful Objects
The RESTful Objects specification comes out of the Naked Objects movement. It is a specification that allows you to create a domain model and expose it through a RESTful API using the Hypermedia As The Engine Of Application State or HATEOAS for short.
As you would expect for the REST based system the domain models are exposed as resources and client applications interact with these through their URI, the standard HTTP Verbs and also the use of both standard and custom HTTP Headers.
It is possible to expose:
- The Domain Object as a resource at the URI
- The properties of the Domain Object as their own child resource
- The actions/commands that can be performed on the Domain Object as their own child resource
For each of the Resource, which can be any of the above, the specification allows you to define how the API should interact with that resource:
- Just to retrieve the Resource you can perform a GET this will be an idempotent operation that will not change the state of the object
- To change the state of a Resource you can perform a PUT and pass through the new representation of that Resource. Again, this is an idempotent operations as you can put the same data as many times as you like and it will retain the same details.
- To delete the Resource you can perform a DELETE.
- If we have a collection as a Resource and you want to add something to that collection then it is a standard approach is to POST the new item to the root of the collection and you will be given back the address at which you can find the new Resource as a 201 Created. This is not an idempotent operation as repeated POSTS may generate multiple new objects.
There is currently both a Java and .NET implementation of the RESTful Objects specification.
Why do I have a problem with it?
I have many concerns about using frameworks like this to expose my domain model to the outside world, at the moment I find developers tend to rush towards a framework that "solves" their problems without first understanding the nature of the problem they are trying to solve or understand the constraints that the framework will place upon them in the future.
1. My Domain Model is Private
The Domain Model is the value of the functionality that we are providing, it reflects the ubiquitous language that we use to communicate internally about the domain and I do not feel that we should be exposing that for the outside world to consume. In Domain Driven Design Eric Evans talks about the Bounded Contexts and also the techniques that we use to ensure that the domain is protected from the outside world, like the use of Anti-Corruption Layers. I think that we need to design our APIs as the Anti-corruption layer for our domain and not build our API out of the domain.
2. My Domain Model Changes
As we work on a project, as we discuss the Domain, we are constantly getting a deeper understanding of the Domain and we are changing our Ubiquitous Language (and hence the Domain Model to reflect those changes). However, when we have exposed our Domain Model to the outside world we have built in rigidity into our systems, if we change the nature of the domain too much we can no longer expose the same objects over the old API and the existing clients break.
3. Domain Modelling != Service Design
I think that it is important to make the distinction between Domain Driven Design and the Service Design/Architecture because the two are not exactly the same thing. They are related concepts, without knowing what operations you need to expose on your domain you cannot know how to build your service, or if you don't understand what operations you need to expose to the clients then you don't know what impact this will have on the domain. However, I think that the domain, in many cases, is richer than the nature of the services that you expose to the world, there may be internal features that you need to have access to in the background that you do not wish to expose over services and you want to keep your service definitions isolated from the domain changes.
I think that when looking at service design we are looking for what we need to expose to the clients and how we are going to expose it, what language we use is important as often the deep understanding that we have of our domain has led to a more abstract Ubiquitous Language and the concepts will make no sense.
4. Exposing Properties...
Part of the specification allows the properties of the domain to be exposed to the client including the ability to change the values. This does not sit well for me in a DDD context as we are constantly talking about the design that is reflecting the actions that people take, it feels like there is an element of just exposing a POCO or POJO object as an RPC endpoint rather than exposing something the actions and the intentions of the client. If we have this freedom, it will be misused.
I think that the specification is very thorough and has a number of points that I need to dig into in much more detail about how they are structuring their URLs for actions and commands but I think that there are some fundamental flaws in using this approach to marry together the buzzwords of REST and DDD.
This specification may be useful to us in the case where you control both the client and the server, and you can deploy everything in one big go (but this is creating a rigid structure). Paraphrasing what Jeff Bezos told people at Amazon "you will write APIs as if they are going to be made public" because he knew that if they did that they would be able to make them public if there was a commercial need for them and look how successful that has been.