5
respostas

Retorno diferente de DTO nos verbos HTTP

Eu aprendi a enviar e receber DTO's de uma maneira diferente, porém eu não sei se está cumprindo boas práticas ou se está errado e eu deveria descartar essa forma:

Classe Controller:

CLASSE CONTROLLER

Classe Service:

CLASSE SERVICE

DTO enviado no controller:

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Aqui nessa classe DTO, a única coisa que eu fiz de diferente foi que eu fazendo da forma que estou fazendo nos controllers, o endereço fica como NULL se caso eu passar o "endereco" do tipo "EnderecoDTO" que também é um record. A forma que achei para que ele registrasse corretamente no BD foi colocar o "endereco" do tipo "Endereco" que é uma classe normal.

5 respostas

Eai Lucas beleza? No seu método de cadastrar, listar atualizar e afins... no ResponseEntity<> Você poderia ter passado a própria RECORD criada ao invés do Objeto Medico ou Object. Como exemplo do que falei abaixo segue o método de listagem:

    public ResponseEntity<Page<DoctorList>> list( @PageableDefault(size = 12, sort = {"nome"}) Pageable pageable){
       return this.doctorService.list(pageable);
    }

Então no caso, você colocou , eu substituiria por ? Porque ela é minha classe de DTO, inclusive você sabe se o que eu falei anteriormente "Aqui nessa classe DTO, a única coisa que eu fiz de diferente foi que eu fazendo da forma que estou fazendo nos controllers, o endereço fica como NULL se caso eu passar o "endereco" do tipo "EnderecoDTO" que também é um record. A forma que achei para que ele registrasse corretamente no BD foi colocar o "endereco" do tipo "Endereco" que é uma classe normal." está correto? Se estiver, sabe como faço para o meu DTO (parametro da classe controller) retornar um outro DTO (no caso o endereço em formato de DTO e não de classe)?

Lucas referente a questão do endereço você faria da seguinte forma, no seu Record de endereço você criaria um construtor no seguinte exemplo:

 public AddressObject (Address address){
        this(address.getLogradouro(), address.getBairro(), address.getCep(),
                address.getCidade(), address.getUf(), address.getComplemento(), address.getNumero());
    }

eai por exemplo no método de cadastrar você passaria no ResponseEntity< Seu Record Aqui > e passaria uma instância de enderecoDTO no body que seria teu Record passando o objeto de persistência Endereco como parâmetro. Como mostrado no exemplo abaixo:

@PostMapping
    @Transactional
    public ResponseEntity<DoctorObject> saveDoctor(@RequestBody @Valid DoctorObject doctorObject, UriComponentsBuilder uriBuilder) {
        Doctor doctor = this.doctorService.insertDoctor(doctorObject);
        URI uri = uriBuilder.path("/doctor/{id}").buildAndExpand(doctor.getDoctorIdentifier()).toUri();
        return ResponseEntity.created(uri).body(new DoctorObject(doctor));
    }

como você pode notar no método acima temos uma conversão do Objeto de persistência Doctor para um DoctorDTO e invés de eu expor meu Objeto Doctor estou expondo o DTO, podendo assim, ter flexibilidade de mostrar os atributos que desejo e evitar assim ataques Mass Assignment

Entendi!

Mas o Post, Get, Put e Delete, da forma que eu fiz, apenas fazendo a mudança que você sugeriu, de mudar o ResponseEntity já estaria correto? ou eu estaria fazendo alguma má pratica?

Lucas as mudanças que sugeri seria uma sim uma boa prática da utilização dos Record no ResponseEntity, entretanto, existem também outras melhorias que você pode fazer no seu projeto. Por exemplo, note que sempre faço opto por fazer a tipagem, observe a seguinte comparação

Código 1:

 URI uri = uriBuilder.path("/doctor/{id}").buildAndExpand(doctor.getDoctorIdentifier()).toUri();

Código 2:

 var pathUri = uriBuilder.path("/doctor/{id}").buildAndExpand(doctor.getDoctorIdentifier()).toUri();

No código 2 apenas fazendo a leitura do código, você conseguiria me dizer qual seria o tipo da varíavel pathUri? Então tenho como boa prática não usar var justamente por que numa leitura de código fora de uma IDE fica mais fácil saber qual o objeto que estou trabalhando. Além disso existem outras melhorias que podemos fazer como por exemplo não ficar dependente da anotação @Autowired, por que se por algum motivo teu objeto não for injetado? Como você consegue garantir a injeção dele? Talvez, ficar dependente da anotação também pode ocasionar problemas e precisamos repensar e melhorar nosso código.