Motivação

Durante o desenvolvimento e consumo de web services RESTful, normalmente empregamos o verbo PUT para realizar alterações em recursos já inseridos no servidor. Nesses casos, além de informar o ID do objeto na URL, também precisamos passar, no corpo da requisição, todos os seus dados, mesmo aqueles que não sofreram alterações. Então, internamente o serviço substitui aquele objeto já existente pelo que acabou de ser recebido, sobrepondo todos os seus atributos.

Na maioria dos casos, no entanto, estaremos interessados em realizar alterações parciais nos objetos, modificando apenas alguns dos seus atributos. Para essa finalidade, o protocolo HTTP dispõe do verbo PATCH que, ao ser utilizado em um serviço que implementa a arquitetura REST, indica que é possível efetuar as alterações desejadas no recurso passando apenas os campos que sofreram alterações.

Neste artigo veremos como implementar, das duas formas, métodos de atualização em aplicações ASP.NET Web API, analisando o que é necessário para permitir as alterações parciais nos registros do banco de dados.

Atualização total com PUT

Por padrão, quando criamos um controller em um projeto ASP.NET Web API, os nomes dos seus métodos (também chamados de actions) representam também o verbo do protocolo HTTP que será utilizado para acessar aquela função. Dessa forma, a action de atualização total, acessada via PUT, deve se chamar Put e pode ter a estrutura apresentada na Listagem 1.

Nesse método recebemos, além do ID, representado por um argumento do tipo int, um objeto do tipo Video, que aqui representa a entidade central do nosso domínio.

Listagem 1. Método Put para atualização total do recurso

        public void Put(int id, [FromBody]Video video)
        {
        var dominio = _videos.FirstOrDefault(x => x.Id == id);

        if (dominio != null)
        {
        dominio.Nome = video.Nome;
        dominio.Genero = video.Genero;
        dominio.DataCadastro = video.DataCadastro;
        }
        }
        
  • Linha 3: Buscamos na nossa coleção (vinda de um DbContext, por exemplo) o objeto que possui o ID indicado no parâmetro;
  • Linhas 5 a 10: Se o objeto realmente existe no banco de dados, alteramos todas as suas propriedades, passando para elas os valores recebidos no argumento vídeo.

Para testar esse serviço, podemos utilizar o Postman, conforme ilustrado na Figura 1, na qual estamos enviando umarequisição PUT para a API e passando o objeto em formato JSON.

Requisição PUT no Postman
Figura 1. Requisição PUT no Postman

Nessa implementação, por mais que não tenhamos modificado alguma(s) das propriedades do objeto, será necessário passá-las no corpo da requisição HTTP. Com isso, é fácil perceber que trafegaremos, desnecessariamente, dados que poderiam ser evitados, aumentando o tráfego de informações na rede e processamento no servidor.

Além disso, caso não haja, na aplicação cliente, um procedimento que garanta o preenchimento completo do objeto a ser enviado para a API, corremos o risco de enviar atributos com valor nulo, que serão persistidos incorretamente no banco de dados.

Atualização parcial com PATCH

Diante da percepção dos possíveis problemas e limitações do verbo PUT, foi criado, em 2010, o PATCH, o qual indica que um método do serviço RESTful é capaz de receber apenas os atributos do recurso que realmente precisam ser alterados.

Para implementá-lo em uma aplicação ASP.NET Web API, precisamos utilizar a classe auxiliar Delta, como pode ser visto na Listagem 2.

Listagem 2. Método Patch para atualizações parciais

        public void Patch(int id, Delta<Video> video)
        {
        var dominio = _videos.FirstOrDefault(x => x.Id == id);

        if (dominio != null)
        {
        video.Patch(dominio);
        }
        }
        
  • Linha 1: Recebemos como parâmetro um objeto do tipo Delta, que é uma classe genérica e, nesse caso, deve referenciar a classe que estamos trafegando, ou seja, Video. Ela nos permite mapear o objeto recebido e passar para nosso model apenas as alterações que de fato ocorreram em suas propriedades;
  • Linha 7 Com o método Patch, da classe Delta, aplicamos no objeto domínio apenas as modificações sofridas nas propriedades que foram recebidas no corpo da requisição.

Agora, para testar esse método no Postman, podemos proceder como na Figura 2. Note que no corpo da requisição passamos apenas uma propriedade no formato JSON.

Requisição PUT no Postman
Figura 2. Requisição PATCH no Postman

Com isso, conseguimos atualizar o objeto sem a necessidade de enviá-lo por completo, melhorando a performance da nossa API e reduzindo o tráfego de dados.