I’ve got a problem designing architecture for an application combining Domain Driven Desing principles with REST. The biggest problem for me here is that the Domain is just interfaces specification and response entities. Of course I can change this common layer as I please, but for now that’s the idea. I need this common layer because I want to be able to plug one of many implementations to the domain-based interface.
So here it comes:
Option 1: I could combine encapsulation with REST with classical objects (just have public methods exposing behaviours and private fields annotated by @JsonProperty), but I need interfaces (or I could use abstract classes), and you can’t have private inherited fields there...
Option 2: I could use public getters annotated by @JsonProperty, but that would break encapsulation
Option 3: So what I thought would be good here, at least from encapsulation point is creating immutable value objects that will be implemented (if you can say that set of public fields is an implementation) in the common layer, and will be use as input and output for specific methods called on domain objects. Is it a good option? I have no idea… It just seems to work well and don’t brake encapsulation principle
I think it basically explains my problem. What I think would be good for the REST API is using Restlet Objects, but it’s a problem for me to wrap my mind around Restlet Objects, that are in fact interfaces implemented by different implementation classes…
I’m attaching some basic architecture diagram, maybe It’ll help you understanding my problem:
I've asked this question to a friend architect and this is what he wrote me:
Let’s think what is REST? REST is just a representation layer, which exposes a view on the system. It already draws a distinction (systems boundaries) between system and its representation, what we have here is classic problem of different responsibilities. I do strongly believe that “value is system boundary”. I wouldn’t expose domain objects, but rather create value objects, which are transformed from and to domain objects. It means creating whole bunch of value objects which represent individual resources at REST layer. Of course if your are in Java world it means creating classes, with getters and setters, but it is definitely worth it. I may sound like fascists but I would draw clear boundary between domain and its representation, you would just need nice mapping layer (there is plenty of these), but I wouldn’t like to see domain objects in JAXRS endpoints (resources). This way you create anticoruption layer between you and and other thirdparty frameworks you use for BPM, so in short it means upgrades and changes in these frameworks will be under YOUR control. So I think you are heading into right direction, but would not use domain classes in JAXRS, and create Value Objects.
I would need to build following layers. BPM engine -> common interface (which in my understanding look like Strategies from DDD) -> VO objects which are build by root aggregates (you need a way to factor these objects), VO should have JSON mapping annotations, not common interfaces -> JAXRS which access root aggregates, gets VO from them -> Jackson does the magic of mapping
So thanks to this you could have stable interface, you don’t want to rebuild your REST layer every time something changes inside of the system. So VO are here to hide how your internal interface (common interfaces) change. Correct me if I am wrong, but you want to create kind of common lowest denominator of BPM engines, to have same model, despite of differences of Activit and jBPM models.
I do think JAXRS should be really thin layer, in application I work on, in couple of places we started to add some logic, you know deadlines, at the end of the day everything exploded in our faces, when people didn’t know that there are some additional rules applied in JAXRS, refactoring was nightmare. Finally we moved to model where JAXRS just reaches for aggregate roots/entities asks for VO and returns it back.