As validações funcionam perfeitamente, mas se eu quiser utilizar uma outra regra de negócio para que a validação ocorra apenas em uma requisição do tipo PUT não consigo.
Por exemplo, se eu quiser, em uma requisição do tipo POST, aceitar o campo código nulo, e fazer com que o back-end gere um novo código, tanto com a anotação @NotNull quanto @NotBlank isso não é possível, pois a validação ocorre antes de bater no método post, já com a anotação @NotBlank, não consigo realizar uma atualização caso algum registro possua o código igual a zero.
Em resumo, a questão é a seguinte, existe a possibilidade de realizar a validação do campo código apenas no momento em que eu for realizar um PUT ?
Se for seguir o padrão REST para implementação, o id neste caso vem como variável de path e não no corpo da requisição, logo, a validação do id não é feita com o objeto de entrada!
No caso de utilizar neste formado em que recebe o id no corpo da requisição o ideal é ter objetos de entrada distintos para cada rota tendo nos mesmos os campos pertinentes com suas validações, entenda estes objetos como sendo “DTOs” e não suas entidades, o uso de objetos de domínio na camada de apresentação tira flexibilidade da sua aplicação, aumenta o acoplamento e dificulta consideravelmente a manutenção e evolução no futuro.
Deixe-me ver se entendi, o que você está me dizendo é que não é uma boa prática realizar a validação por meio do Bean Validation, deixando a responsabilidade para a Service?
Então devo criar DTOs também para as entidades de domínios?
Ou devo entender isso para o caso de uma atualização/exclusão de registro?
Sobre a parte de passar ou não o ID pela url (path variable). Pense assim:
O POST é usado quando for inserir algum recurso no servidor, ou seja, toda vez que ele for chamado, irá causar alguma alteração no servidor, com isso, vc não tem como fazer alguma ação usando POST num recurso conhecido, pois o intuito é criar um.
O PUT é usando para alterar um recurso existente ou inclui-lo caso não exista. A diferença é que as ações PUT são idempotentes, ou seja, ao executar 10 vezes a mesma ação (idêntica, com os mesmos parâmetros), o servidor só deverá ter alguma alteração na primeira ação e as outras não devem fazer nada.
De acordo com as explicações, as URLs POST, por não conhecerem o recurso a ser afetado, não tem identificação, ex.:
POST /api/usuarios # cria um novo usuario
POST /api/usuarios/1/telefones # cria um novo telefone para o usuário de ID 1
E como o PUT é feito sobre recursos conhecidos (mesmo que ainda não existam), as URLs levam o identificador:
PUT /api/usuarios/1 # cria ou altera um usuario com o ID 1
PUT /api/usuarios/1/telefones/2 # cria ou altera um telefone de ID 2 para o usuário de ID 1
Utilizar Bean Validation é sim uma boa prática, eu particularmente considero excelente o uso do mesmo e super recomendo!
Agora, utilizar uma classe de domínio, seu “model” neste caso como sendo objeto único que é utilizado para validação de dados de entrada, persistência e imagino que seja também utilizado como objeto resposta, isso sim é uma prática ruim, “ah mas assim funciona…” sim, funciona, porém não deixa de ser uma prática ruim.
A ideia que eu quis te passar é a seguinte, criar objetos únicos para tratar a entrada de dados e também a saída de dados da aplicação, objetos estes conhecidos como DTOs, para os objetos de entrada a sugestão seria de atribuir à eles as anotações de validação de dados, saca?
Muito obrigado @Jonathan_Medeiros e @Lucas_Camara, notei que as duas respostas se complementam, vou utilizar um DTO para realizar minhas validações no back-end, criando não apenas um POJO, mas um objeto um pouco mais “rico”, assim, consigo implementar algumas regras adicionais de validação.