piechos
piechos

Reputation: 123

Mixing entity with payload (dto) in spring boot - best practice

Is it good practice to have one class being both entity (mapped and stored in the database) and payload (object serialized and returned form REST endpoint) at the same time?

I heard somewhere that entities should never go higher than service layer but rather should be mapped to DTO objects in services and then these DTO should be returned to controllers.

I personally think this is bad practice because in such class we mix annotations for serializing to JSON and for mapping object to the database which makes the code hard to read.

But maybe there are some other arguments. What do you think?

Upvotes: 1

Views: 4390

Answers (2)

jbx
jbx

Reputation: 22188

Well each case has its own merit. But typically in realistic cases they are different.

Conceptually, what you are exposing as an API will probably be different from what you are storing in the database, unless your service is a really dumb one.

The 3 layers are separated for a reason.

The Controller acts as the front end receiving requests in a particular format. It could be a JSON payload from a RESTful request, it could be a simple plain old form submission. It performs validations and pre-processing of the request to be passed to the other services or components.

The Service acts as the business logic layer. What was passed in a request is not necessarily mapping one to one to what is processed in this layer. It might invoke other services, it might break the request down into smaller separate pieces, it might even queue the request for later processing, as is typically done in CQRS kinds of architectures. It might transform the request it receives to entities to pass to a repository. Furthermore, the service might be consumed from other services or multiple controllers.

The Repository is then handling the logic with the database entities and their relationships. The entities it handles will be more aligned with the database tables and while still being objects, will have more of a relational kind of design.

Another thing you have to keep in mind is that the internal implementation and the repository might be modelled differently from the API. It takes a lot of skill and attention to create an API which is abstract to the right levels, clean and user friendly enough, and most best practices suggest to actually do this 'contract first' without letting the implementation of the API influence your DTO design.

Upvotes: 1

Rentius2407
Rentius2407

Reputation: 1148

Personally I think it is good practice to separate the layers. I would motivate with the following.

Lets say you have a client, client A.

Client A integrates into your system via a Restful endpoint and expects account information. You version the Rest endpoint and return the versioned Account entity.

@Entity
public class Account {
   private Long id;
   private String firstname;
   private String lastname;

   //Getters and setters are omitted for the sake of brevity
}

Client A is happy with the info and uses it for 6 months.

After the 6 months your database team starts a cleanup/refactoring process and changes lastname to surname and firstname to name. The following needs to change, because all of them might touch the object:

  1. Database Layer
  2. Persistence Layer
  3. Business Layer
  4. Presentation Layer

As you can see the small change trigger a lot of changes. It also breaks the contract of the versioned Restful endpoint.

If the Entity was converted to a DTO say in the Business Layer the changes will be contained inside your application boundary and of minimal impact. The contract also stays intact and no changes are needed on the client's side.

Upvotes: 3

Related Questions