Как управлять распространением DTO для различных операций APIJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Как управлять распространением DTO для различных операций API

Сообщение Anonymous »

У меня возникли проблемы с управлением DTO.
Я работаю следующим образом: у меня есть многоразовый DTO под названием PhoneResponseDTO, который используется как в findAll, так и в findByID. Затем я создал DTO для каждой операции, такой как «Создание», «Обновление» и «Удалить».
Ну, я подумал: я получаю RequestDTO, если все идет хорошо, я конвертирую этот RequestDTO в Entity с помощью метода toEntity(). После сохранения и теперь, чтобы ответить, что он создан, я преобразую его в CreatedResponseDTO с помощью метода toResponseDTO(). То же самое происходит с операциями обновления и удаления.
RequestDTO -> Entity -> ResponseDTO
Ответные DTO
public record PhoneResponseDTO(
String description,
String brand,
// ...
String personId,
String personName
) {
}

public record PhoneCreatedResponseDTO (
String message, // Successfully created phone
String description,
String personId,
String personName,
LocalDateTime createdAt
) {
}
// I created deletedDTO, updateDTO

Сервис
@Service
public class PhoneService {
private final PhoneRepository phoneRepository;
private final PersonRepository personRepository;

@Autowired
public PhoneService(PhoneRepository phoneRepository, PersonRepository personRepository) {
this.phoneRepository = phoneRepository;
this.personRepository = personRepository;
}

public PhoneResponseDTO findById(Long id) {
return phoneRepository.findById(id).map(this::toResponseDTO)
.orElseThrow(() -> new NotFoundException("Phone not found with ID: " + id));
}

public PhoneCreatedResponseDTO save(PhoneDTO phoneDTO) {
Person person = personRepository.findById(phoneDTO.personId())
.orElseThrow(() -> new NotFoundException("Person not found with ID: " + phoneDTO.personId()));
Phone phone = toEntity(phoneDTO);
Phone savedPhone = personRepository.save(phone);
return toCreatedResponseDTO(savedPhone);
}

// TO LIST

// Used in findAll & findById
private PhoneResponseDTO toResponseDTO(Phone phone) {
return new PhoneResponseDTO(
phone.getDescription(),
phone.getBrand(),
// ..
phone.getPerson().getDni(),
phone.getPerson().getName()
}

// TO CREATE

// This "Helper" is used to pass the RequestDTO to converto to an Entity
private Phone toEntity(PhoneRequestDTO phoneRequestDTO) {
Phone phone = new Phone();
phone.setDescription(phoneDTO.description());
// ...
phone.setPerson(person);
return phone;
}

// "Helpers" used with Created entity to pass to the Created Response Dto
private PhoneCreatedResponseDTO toCreatedResponseDTO(Phone phone) {
return new PhoneCreatedResponseDTO(
"Phone created successfully",
phone.getDescripcion(),
phone.getPerson().getDni(),
phone.getPerson().getName(),
LocalDateTime.now()
);
}
// Update and Delete Helpers ...
}

Контроллер
@RestController
@RequestMapping("/phone")
public class PhoneController {

private final PhoneService phoneService;
@Autowired
public PhoneController(PhoneService phoneService) {
this.phoneService = phoneService;
}
// ...
@PostMapping
public ResponseEntity save(@RequestBody PhoneRequestDTO phoneRequestDTO)
return ResponseEntity.status(HttpStatus.CREATED).body(phoneService.save(phoneRequestDTO));
}
//...
}

Но когда я начал создавать ResponseDTO для каждой сущности, проект начал сильно разрастаться, поскольку каждая сущность имела как минимум 4 DTO. Меня беспокоит, правильно ли я управляю DTO, поскольку у меня есть идея, что именно данные, которые я передаю через свой ResponseDTO, будут использоваться для отображения во внешнем интерфейсе.
Я искал способы улучшить организацию и сопоставление DTO с помощью MapStruct или также создать общий класс под названием ApiResponse, который затем будет работать с аннотацией @RestControllerAdvice, которая будет работать аналогично исключениям, но не является исключениями. Но что мне делать с исключениями, которые я уже создал в своем классе с помощью аннотации @ControllerAdvice? Я читал комментарии, что, возможно, лучше оставить MapStruct в стороне и сделать это с помощью статических функций или чего-то подобного. Я не совсем понимаю, что они имели в виду, но думаю, что это должно быть что-то похожее на вспомогательные методы, которые я использовал для преобразования из RequestDTO -> затем использовать toEntity() -> ResponseDTO().
Имея много DTO, и даже несмотря на то, что моя Служба хорошо с этим справляется, а затем отображает его через определенный ResponseDTO для каждой операции, должен быть лучший способ улучшить организацию и отображение DTO. Или, как сейчас, я не хочу в будущем создавать избыточные DTO.
@ControllerAdvice
public class ControllerExceptionHandler extends ResponseEntityExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(ControllerExceptionHandler.class);

@ExceptionHandler(NotFoundException.class)
public ResponseEntity handleNotFoundException(NotFoundException e, WebRequest request) {
logger.error("Exception occurred: {}", e.getMessage(), e);

CustomErrorMessage customErrorMessage = new CustomErrorMessage(
HttpStatus.NOT_FOUND.value(),
LocalDateTime.now(),
e.getMessage(),
request.getDescription(false));

return new ResponseEntity(customErrorMessage, HttpStatus.NOT_FOUND);
}

@ExceptionHandler(DuplicateResourceException.class)
public ResponseEntity handleDuplicateResourceException(DuplicateResourceException e, WebRequest request) {

logger.error("Exception ocurred: {}", e.getMessage(), e);
CustomErrorMessage customErrorMessage = new CustomErrorMessage(
HttpStatus.CONFLICT.value(),
LocalDateTime.now(),
e.getMessage(),
request.getDescription(false));

return new ResponseEntity(customErrorMessage, HttpStatus.CONFLICT);
}
}


Подробнее здесь: https://stackoverflow.com/questions/798 ... operations
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»