2

We know that combining a domain entity, a DTO, and a REST API serialization class into one won't pass code review:

@JsonInclude(JsonInclude.Include.NON_NULL) @Data @Builder @Entity @Table(name = "users") public class UserEntity { ... 

I can justify investing the time to separate such a class into distinct @Entity and DTO classes, ensuring each has a clear, single responsibility.

But how about taking it one step further: separating the DTO for internal use (domain or application logic) from a dedicated class designed specifically for REST API serialization? This could simplify version-specific serialization and make the layers of the application more maintainable.

For example, the following minimal code sample demonstrates separation of concerns by using JPA, Lombok, and Jackson annotations on different classes representing the same conceptual object:

Entity Class (JPA):

import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name = "users") public class UserEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String username; private String password; private String email; // Getters and setters } 

DTO Class (Lombok):

import lombok.Data; import lombok.Builder; @Data @Builder public class UserDTO { private String username; private String email; } 

JSON Representation Class (Jackson):

import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonInclude; @JsonInclude(JsonInclude.Include.NON_NULL) public class UserJson { @JsonProperty("user_name") private String username; @JsonProperty("email_address") private String email; // Getters and setters } 

Service Class to Convert Between Entity and DTO:

public class UserService { public UserDTO convertToDTO(UserEntity userEntity) { return UserDTO.builder() .username(userEntity.getUsername()) .email(userEntity.getEmail()) .build(); } public UserJson convertToJson(UserDTO userDTO) { UserJson userJson = new UserJson(); userJson.setUsername(userDTO.getUsername()); userJson.setEmail(userDTO.getEmail()); return userJson; } } 

When is it advisable to separate DTO from JSON?

For example, when we need to maintain multiple versions of our API, separate JSON classes allow us to handle version-specific serialization without affecting your internal DTOs, right? Is there a better approach to that?

Or... when there's significant data transformation between our internal representation (DTO) and the API contract (JSON), separating them can make these transformations more manageable. Does this make sense? Or does it point at fundamental flaw in the system design?

7
  • 4
    "When is it advisable to separate DTO from JSON?" Never? That's one of the main reasons DTOs exist: to serialize them into any format you want. Would you also create a separate class for XML? CSV? All of them exactly the same? Form over content. Commented Dec 3, 2024 at 6:17
  • 7
    "We know that entities that are also DTOs and also REST API JSONs won't pass code review": So, your company has a guideline that doesn't allow that. Depending on the project complexity, and ignoring any company guidelines, anything can be a good solution, from one-class-does-it-all to a confusingly complex zoo of classes and interfaces, all representing the same concept, just for different purposes. Whoever tells you "you have to do it exactly this way" should also state the circumstances where this advice applies. Commented Dec 3, 2024 at 8:03
  • 1
    @RalfKleberhoff Thank you for your comment. Please post it as an answer and I will accept it. In the answer, if you could elaborate on an example that justifies not following the "Never" rule explained in the previous comment, that would help me better understand. Commented Dec 3, 2024 at 13:50
  • 2
    On second thought, I voted to reopen. There are some valid technical considerations that affect this decision even if there is an element of subjectivity to it. Commented Dec 3, 2024 at 14:27
  • 3
    This question seems to be built on inaccurate language. Case in point: "separate JSON classes allow us to handle version-specific serialization without affecting your internal DTOs, right?" What you're referring to as "JSON class" here is what is commonly referred to as a DTO. What you're referring to as an "internal DTO" is generally referred to as a domain model (or similarly private data structure). Commented Dec 3, 2024 at 23:14

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.