DTOを使うことによる悩み


プロジェクトを行う過程で、いつものようにdtoを使います...悩みがある各層が良い分離形式で使用されることを望んでいますが、想像していたほどではありません.
まず、サービス層からDTO<>Entityに変換されたコードを含む以下のコードが実現される.

Controller

    @PostMapping
    public ResponseEntity<Object> create(@Valid RequestDTO requestDTO) {
        ResponseDTO response = service.create(RequestDTO);
        return ResponseEntity.status(HttpStatus.CREATED).body(response);
    }

Service

    public ResponseDTO create(RequestDTO parameterDTO) {
        Entity entityData = mapper.toEntity(parameterDTO);
        Entity result = repository.save(entityData);
        ResponseDTO dto = mapper.toDto(result);
        return dto;
    }

悩み事


ビューに必要なデータが変更された場合、DTOは変更され、コントローラのみを変更するのではなく、サービスも変更する必要があります。


クライアントが要求したデータが変更された場合、ビジネスロジックも一緒に変更され、気まずいように見えます.ドメインサービスがドメインサービスの役割を果たすことを望んでいます.

考えたことがある。こうぞう


上記の問題を解決するために、DTOを1つの位置に固定するのではなく、DTOを同時に使用するのはどうですか.という考えが生まれた.
Service Layerでは、Entityをそのまま使用すると問題になる可能性がある(Entity外部露出、ループリファレンス問題など)ため、従来の方式でDTO<>Entityロジックを導入する.ただし、Service Layerが使用するDTOはビューではなく、汎用的なDTOであり、コントローラを使用してDTOを使用するか、DTOを必要な構造に変更して再使用することができます.

Controller

    @PostMapping
    public ResponseEntity<Object> create(@Valid RequestDTO requestDTO) {
    	EntityDTO dto = mapper.toEntityDto(requestDTO);
    	EntityDTO resultDto = service.create(dto);
        ResponseDTO response = mapper.toResponse(resultDto);
        return ResponseEntity.status(HttpStatus.CREATED).body(response);
    }

Service

    public EntityDTO create(EntityDTO parameterDTO) {
        Entity entityData = mapper.toEntity(parameterDTO);
        Entity result = repository.save(entityData);
        EntityDTO dto = mapper.toDto(result);
        return dto;
    }
これはDTO<>DTOの構造のように変化し、クライアントが要求するデータが変化し、サービスを汎用DTOに変換することで、サービスのロジックが変化しないように使用できます.
サービス層が使用するオブジェクトは、エンティティとエンティティDTOとして一貫して使用することができる.