Search code examples
javaspringdto

Which DTO class is the correct structure?


I'm learning about DTO's, and I have a question. Which of these 2 examples is the correct way to make a DTO class. First Example

package com.example.matchescrud.dto;

import com.example.matchescrud.dto.response.MatchResponseDTO;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;

@AllArgsConstructor
@NoArgsConstructor
@Data

public class TeamDTO {
    private Long id;
    private String name;
    private DivisionDTO division;
    private CityDTO city;
    private StadiumDTO stadium;
    private List<MatchResponseDTO> homeMatches;
    private List<MatchResponseDTO> awayMatches;
}

Second example

package com.example.matchescrud.dto;

import com.example.matchescrud.model.entity.City;
import com.example.matchescrud.model.entity.Division;
import com.example.matchescrud.model.entity.Match;
import com.example.matchescrud.model.entity.Stadium;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;

@AllArgsConstructor
@NoArgsConstructor
@Data

public class TeamDTO {
    private Long id;
    private String name;
    private Division division;
    private City city;
    private Stadium stadium;
    private List<Match> homeMatches;
    private List<Match> awayMatches;
}

Object attributes should be DTO's or they have to be normal objects?


Solution

  • As far as I can tell, the question is, "Should DTOs contain DTOs, or the 'real' objects?" In your two examples, the generic type of the Lists is:

    1. List<MatchResponseDTO>
    2. List<Match>

    #1 is correct. If your DTO has non-DTO data in it, it's not a complete DTO.

    I'll elaborate with an example: Imagine you have a Team with List<Player>s. If the Player has login information such as a password, you wouldn't want to expose it.

    Here's another example: Match may be object oriented in such a way that it has cyclical references. e.g., Match -> Field -> List<Match> matches. That may cause issues when converting the DTO into json (for example). Eventually, most objects will end up needing to look like DTOs to work around this issue.

    Instead, you should create a clear separation between DTOs and non-DTO objects. This will allow you to design the non-DTO parts independently from the data transfer technology.

    For further reading, search for "Domain Driven Design," particularly the patterns. Though I will warn you, most explanations are so abstract they are difficult to learn from.