I have an application that receives a JSON message and then deserializes it into a POJO. I've been studying the Onion Architecture for a couple of weeks now and I've stumbled across a tecninal dilema for this situation. Since I'm using the Jackson Deserializer I was forced to use Jackson Annotations in order to assist the deserialization process. This Jackson POJOs are needed by the application core and here comes the problem. Since deserialization is an infrastructure concern it wouldn't be correct to have classes with Jackson annotations in my core, right?
I see 2 options:
1 - My core will have a POJO similar to the Jackson POJO but without its annotations. The Jackson POJOs will be in the infrastructure and then I'll use a mapping framework to map the Jackson POJOs to Domain POJOs.
POJO in the infrastructure layer:
public class MyUser {
private String firstName;
private String lastName;
@JsonProperty("first_name")
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
@JsonProperty("last_name")
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
POJO in the core layer:
public class MyUser {
private String firstName;
private String lastName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
2 - Assume that Jackson is cross-cutting and therefore can be used through the layers.
I believe that option 1 is more suitable considering that I'm following the Onion Architecture. However, sticking to this option will force me to duplicate objects and that does not sound good to me.
Is there really only this two options? Any advice?
Your solution one is a well known solution the Data Transfert Object Design Pattern or DTO if you want to learn more about about it.
In my point of view those are not object duplication. They are different representation of the same domain concept, each adapted to the need of a specific application layer. And as every pattern there is times where it's mandatory to use them and some where it's a useless and more damaging than anything.
A story from my own experience : we had a project where we chose to use the same POJOs for every layer to avoid duplication and having to handle mapping. Few weeks later we had minor cross-concerns issues that we "hacked out".
A bit later those issues became more serious (performance, database problems in the API layer...) and the hack to fix them worst. In the end after a lots of headache we agreed that mapping and POJOs duplication made sense.
But the opposite can also happen : you can make strict layering with mapping for a simple CRUD application with very few logics at all. And then a strict layered architecture is a waste of time and effort.
As often the answer is : it depends on what you are trying to build. The bigger and more complex an application is and will be (scalability is a real matter here), the more strict the architecture have to be. But a simple application (or any simple node of a larger structure) need to stay simple.
Hope it helped!