В каком слое должно происходить преобразование DTO / Entity.
Имея следующую структуру в приложении Spring Mvc:
- Контроллер
- Сервис
- Репозиторий
Подход, который я использую сейчас, где уровень обслуживания @Transactional
.
@RestController
public class ExampleController {
@Autowired
private ExampleService exampleService;
@Autowired
private ExampleMapper exampleMapper;
@GetMapping("/examples")
public ResponseEntity<List<ExamleDto>> getAll() {
var examples = exampleService.getAll();
return ResponseEntity.ok(exampleMapper.examplesToExampleDtos(examples));
}
@PostMapping("/examples")
public ResponseEntity<Void> create(@RequestBody @Valid ExampleCreateDto createDto) {
var example = exampleService.create(createDto)
return ResponseEntity.created(URI.create("examples/" + example.getId()).build();
}
// PUT, DELETE, ...
}
@Service
@Transactional
public class ExampleService {
@Autowired
private ExampleRepository exampleRepository;
@Autowired
private ExampleMapper exampleMapper;
public List<Examle> getAll() {
var examples = exampleRepository.findAll();
return examples;
}
public void create(ExampleDto exampleDto) {
var example = exampleMapper.asExample(exampleDto);
return exampleRepository.save(example);
}
}
public interface ExampleRepository extends JpaRepository<Example, Long> {
Почему я выбрал этот подход :
Уровень обслуживания является транзакционным, поэтому всякий раз, когда мы возвращаемся к контроллеру, все изменения сбрасываются (например, поле версии).
Это заставляет вас думать о своем entitygraph, допустим, у вас есть сущность Person, у которой есть список отделов. Допустим, PersonDto содержит также список DeparmentDtos, он вынуждает вас извлечь все отладки до того, как вы получите руку, или вы столкнетесь с LazyInitializationException на уровне контроллера. Что, на мой взгляд, является хорошей вещью, потому что, если бы вы выполняли сопоставление в сервисе, вы выполняли бы N + 1 запросов (N - количество отказов), не осознавая этого.
Сервисы, которые нуждаются друг в друге чтобы выполнить там свои бизнес-задачи, работайте над моделью сущностей вместо модели DTO, которая может иметь некоторую валидацию (@NotNull, @Size, ...), которая должна проверяться только тогда, когда она поступает извне, но внутренне не все проверки должны быть применены. Бизнес-правила по-прежнему будут проверяться на уровне службы как часть метода службы. Единственное, что здесь - это то, что для обновления / создания сервис все еще связывается, передавая dtos iso сущностей.
Я много гуглил эту топи c, но не смог найти окончательный ответ.