5
respostas

[Dúvida] PUT METHOD DUVIDAS EM GERAL

Gostaria de tirar algumas dúvidas que tem surgido ao longo das adaptações e alguns conhecimentos que ja possuo:

  1. Os tipos de Retornos abaixo faz diferença?
@PutMapping
    @Transactional
    public ResponseEntity atualizar(@RequestBody @Valid DadosToUpdateMedicosDTO dadosUpdateMedicos) {
        MedicoModel entityModel = repository.getReferenceById(dadosUpdateMedicos.id());
        entityModel.updateDadosMedicos(dadosUpdateMedicos);

        return ResponseEntity.ok(new ResponseBodyDadosMedicosDTO(entityModel));
        return ResponseEntity.status(HttpStatus.OK).body(new ResponseBodyDadosMedicosDTO(entityModel));
    }
  1. Ao realizar um update dos dados em record do 'DadosToUpdateMedicosDTO', em endereço no record do 'DadosEnderecoDTO' , está permitindo armazenar dados em brancos ou nulos das variaveis criadas: nome, telefone e enderecoDTO(em geral todos). Uma vez que já existe a validação precisaria refazer essas validações? Como ficaria?
public record DadosToUpdateMedicosDTO(
        @NotNull
        Long id,
        String nome,
        String telefone,
        @JsonProperty("endereco")
        @JsonAlias({"enderecoDTO", "endereco DTO", "endereco", "endereco-DTO"})
        DadosEnderecoDTO enderecoDTO) {

}
public record DadosEnderecoDTO(
        @NotBlank
        String logradouro,
        @NotBlank
        String bairro,
        @NotBlank
        @Pattern(regexp = "\\d{8}")
        String cep,
        @NotBlank
        String cidade,
        @NotBlank
        String uf,
        String complemento,
        String numero) {
}
  1. Pensando em consolidar uma API e os dados criados DTO's, porque são enviados dados direto da entidade Medico no corpo da response? Seria mais ideal criar um DTO com alguns dados mais específicos e enviar? Ou realmente tem que ser os dados literais que estão no db?
5 respostas

Olá Neander!

Vamos às suas dúvidas:

  1. Tipos de Retornos no Método PUT:

    Ambos os retornos são equivalentes em termos de resultado, sendo que a primeira opção é menos verbosa.

  2. Validação de Dados em DadosToUpdateMedicosDTO:

    Se os dados estão sendo armazenados com valores em branco ou nulos, é necessário garantir que as validações estão sendo aplicadas corretamente. No seu DadosToUpdateMedicosDTO, você pode adicionar as anotações de validação apropriadas para nome, telefone e enderecoDTO:

    public record DadosToUpdateMedicosDTO(
        @NotNull Long id,
        @NotBlank String nome,
        @NotBlank String telefone,
        @JsonProperty("endereco")
        @JsonAlias({"enderecoDTO", "endereco DTO", "endereco", "endereco-DTO"})
        @Valid DadosEnderecoDTO enderecoDTO) {
    }
    

    Certifique-se de que as anotações de validação estão importadas corretamente e que o Spring está configurado para validar os campos.

  3. Uso de DTOs na Resposta da API:

    É uma boa prática usar DTOs (Data Transfer Objects) para enviar dados específicos na resposta da API, em vez de enviar a entidade diretamente. Isso ajuda a proteger a estrutura interna do seu banco de dados e permite que você controle exatamente quais dados são expostos. No seu caso, criar um DTO com os dados específicos que você deseja retornar é uma abordagem recomendada. Por exemplo:

    public class MedicoResponseDTO {
        private Long id;
        private String nome;
        private String telefone;
        private EnderecoDTO endereco;
    
        // Construtores, getters e setters
    }
    

    E então, você pode usar esse DTO no retorno do seu método:

    @PutMapping
    @Transactional
    public ResponseEntity atualizar(@RequestBody @Valid DadosToUpdateMedicosDTO dadosUpdateMedicos) {
        MedicoModel entityModel = repository.getReferenceById(dadosUpdateMedicos.id());
        entityModel.updateDadosMedicos(dadosUpdateMedicos);
    
        MedicoResponseDTO responseDTO = new MedicoResponseDTO(entityModel.getId(), entityModel.getNome(), entityModel.getTelefone(), entityModel.getEndereco());
        return ResponseEntity.ok(responseDTO);
    }
    

Espero ter ajudado e bons estudos!

Perfeito! Obrigado pelos esclarecimentos,

ao realizarmos a chamada do PUT do método acima, realmente tinha esquecido de colocar as validações. Porém ainda continua dando um erro em relação aos dados do endereço, permitindo nulos ou vazios. Ai fica mais uma dúvida, quando é declarado Objecto Rerence de ('DadosEnderecoDTO') no record 'DadosToUpdateMedicosDTO', automaticamente deveriam ir todas as validações quando fizesse alguma atualização de dados?

public record DadosEnderecoDTO(
        @NotBlank
        String logradouro,
        @NotBlank
        String bairro,
        @NotBlank
        @Pattern(regexp = "\\d{8}")
        String cep,
        @NotBlank
        String cidade,
        @NotBlank
        String uf,
        String complemento,
        String numero) {
}

PostmanImage

As validações não sei feitas em cascata. Se no seu record tem algum atributo que é uma outra classe/record e nela tem anotações do bean validation que você deseja executar, precisa adicionar o @Valid nesse atributo. Ex:

public record DadosToUpdateMedicosDTO(
        @NotNull
        Long id,
        String nome,
        String telefone,
        
        @JsonProperty("endereco")
        @JsonAlias({"enderecoDTO", "endereco DTO", "endereco", "endereco-DTO"})
        @Valid
        DadosEnderecoDTO enderecoDTO) {

}

Entendi! Muito obrigado pela explicação e paciência para ajudar meu crescimento.

Mas ainda tenho uma dúvida, ao criar as validações no 'DadosToUpdateMedicosDTO'

public record DadosToUpdateMedicosDTO(
    @NotNull Long id,
    @NotBlank String nome,
    @NotBlank String telefone,
    @JsonProperty("endereco")
    @JsonAlias({"enderecoDTO", "endereco DTO", "endereco", "endereco-DTO"})
    @Valid DadosEnderecoDTO enderecoDTO) {
}

Quando faço a realização de atualização somente por exemplo do telefone:

{
    "id": "1",
    "telefone": "21988887777"
}

Eu recebo um Status:400 Bad Request pedindo que os outros campos @NotBlank

[
    {
        "codes": [
            "NotBlank.dadosToUpdateMedicosDTO.nome",
            "NotBlank.nome",
            "NotBlank.java.lang.String",
            "NotBlank"
        ],
        "arguments": [
            {
                "codes": [
                    "dadosToUpdateMedicosDTO.nome",
                    "nome"
                ],
                "arguments": null,
                "defaultMessage": "nome",
                "code": "nome"
            }
        ],
        "defaultMessage": "não deve estar em branco",
        "objectName": "dadosToUpdateMedicosDTO",
        "field": "nome",
        "rejectedValue": null,
        "bindingFailure": false,
        "code": "NotBlank"
    }
]

Como que eu faço par alterar somente o campo específico? Pensando no cliente e no frontend.

Aí vai ser igual foi feito no curso. Os campos cuja atualização forem opcionais, você não coloca anotações de validação.