Motivação

No desenvolvimento de serviços RESTful, normalmente as operações de um CRUD (Create, Read, Update e Delete) são iniciadas através de métodos que utilizam, respectivamente, os verbos POST, GET, PUT e DELETE do protocolo HTTP. Nesse cenário, independentemente da linguagem e framework que se esteja adotando, é fundamental saber como empregar esses verbos e implementar tais operações, de forma que elas possam ser compreendidas e utilizadas com facilidade pelas aplicações clientes.

Nesse artigo veremos como criar web services RESTful para disponibilizar as operações de um CRUD explorando os recursos do framework NancyFx e do Entity Framework Code First.

Saiba mais sobre o framework NancyFx

Passo 1: Criar o projeto

Nesse exemplo simularemos um cadastro de filmes, que nos permitirá explorar todas as operações de um CRUD. Então, começaremos criando um novo projeto no Visual Studio, a partir do menu File > New > Project e escolhendo o template Nancy Application with ASP .NET hosting.

O próximo passo será a instalação da biblioteca do Entity Framework, que pode ser feita ao acessar o menu Tools > NuGet Package Manager > Package Manager Console e na janela que será aberta, executar o comando:

 Install-Package EntityFramework 

Passo 2: Criar o model

Logo após, devemos criar uma nova pasta, na solution, chamada Infra, e dentro dela adicionar dois arquivos: Filmes.cs, contendo a entidade principal do nosso sistema e cujo código pode ser visto na Listagem 1; e Contexto.cs, com a classe de contexto que fará a comunicação com a base de dados, como podemos ver na Listagem 2.

Ambas as classes são bastantes simples, e possuem apenas códigos comumente utilizados em aplicações nas quais o Entity Framework é adotado para o acesso ao banco de dados.


01 public class Filme
02 {
03     [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
04     public int Id { get; set; }
05     [StringLength(100)]
06     public string Nome { get; set; }
07 }
Listagem 1. Entidade Filme

01 public class Contexto : DbContext
02 {
03     public Contexto() : base("name=Locadora")
04     {
05     }
06
07     public virtual DbSet<Filme> Filmes { get; set; }
08 }
Listagem 2. Classe de contexto do Entity Framework
Saiba mais sobre o Entity Framework Code First

Passo 3: Adicionar dados

Com o projeto criado e configurado, implementaremos agora os métodos correspondentes ao CRUD no nosso serviço. O primeiro deles será o POST, responsável por adicionar novos registros à base de dados. Para isso, devemos configurar o nosso IndexModule, que é gerado automaticamente pelo Visual Studio ao criarmos o projeto NancyFx. Veja a Listagem 3.


  01 public class IndexModule : NancyModule
  02 {
  03  var _contexto = new Contexto();
  04  _contexto.Database.CreateIfNotExists();
  05  public IndexModule() : base("/filmes")
  06  {
  07      Post["/"] = _ =>
  08      {
  09          var filme = this.Bind<Filme>();
  10          _contexto.Filmes.Add(filme);
  11          _contexto.SaveChanges();
  12         return HttpStatusCode.OK;
  13      };
  14  }
  15 }
  
Listagem 3. Classe IndexModule configurada para aceitar o POST

Linha 03: Instanciamos o arquivo de contexto do Entity Framework;

Linha 04: Criamos a base de dados, caso ela não exista;

Linha 05: Configuramos a rota desse módulo, nesse caso, para /filmes;

Linha 07: Configuramos o método que tratará as requisições via POST;

Linha 09: Recebemos os valores do POST e os convertemos para um objeto do tipo Filme com o método Bind();

Linhas 10 e 11: Inserimos o novo registro na base de dados e salvamos as alterações;

Linha 12: Retornamos o status OK (200), informando que o método foi bem-sucedido.

Agora, caso desejemos testar a aplicação e verificar como os dados são recebidos pelo módulo do NancyFx, devemos adicionar um breakpoint na linha 8 da Listagem 3 e executar o projeto. Para testar nosso serviço, utilizaremos o Postman - uma extensão do Google Chrome para enviar requisições HTTP - que deve ser configurado de acordo com a Figura 1.


Figura 1. Configuração do Postman

Após inserir a URL do serviço e um valor para a propriedade Nome na aba Body, basta clicar em Send. Nesse momento, podemos voltar ao Visual Studio e analisar as variáveis no código quando a execução parar no breakpoint, como mostra a Figura 2.


Figura 2. Valores recebidos no POST

Passo 4: Listar informações

O próximo método que iremos implementar será o GET, a partir do qual retornaremos todos os registros já cadastrados ou buscaremos um específico, a partir do seu identificador. A Listagem 4 demonstra o código que deve ser inserido no IndexModule.


  01 Get["/"] = x =>
  02 {
  03     var filmes = _contexto.Filmes.ToList();
  05     return Response.AsJson(filmes);
  07 };
  08
  09 Get["/{id:int}"] = parameters =>
  10 {
  11     int id = parameters.id;
  13     var filme = _contexto.Filmes.FirstOrDefault(x => x.Id == id);
  15     return Response.AsJson(filme);
  16 };
  
Listagem 4. Métodos que tratarão as requisições GET

Linha 01: Configuramos o primeiro método Get, que não recebe parâmetros;

Linha 03: Obtemos todos os objetos na coleção Filmes do contexto do Entity Framework;

Linha 05: Retornamos todos os registros em formato JSON;

Linha 09: Configuramos o segundo método Get, agora recebendo um parâmetro chamado id do tipo inteiro;

Linha 11: Recebemos o valor do parâmetro e o passamos para uma variável local;

Linha 13: Buscamos no banco de dados o registro que corresponda ao id especificado;

Linha 15: Retornamos o registro selecionado no formato JSON.

Nesse momento, para que possamos testar os métodos de listagem de dados, basta enviarmos requisições GET pelo Postman para as rotas /filmes e /filmes/{id buscado}.

Passo 5: Alterar registros

Dando continuidade ao CRUD, vamos criar o método que possibilitará a atualização dos dados. Para isso, teremos um método que tratará as requisições realizadas com o verbo HTTP PUT. A Listagem 5 demonstra essa implementação.


  01 Put["/{id:int}"] = parameters =>
  02 {
  03  Filmes filme = this.Bind<Filmes>();
  04  filme.Id = parameters.id;
  05                 
  06  _contexto.Entry(filme).State = EntityState.Modified;
  07  _contexto.SaveChanges();  
  08
  09  return HttpStatusCode.OK;
  10 };
  
Listagem 5. Método que tratará requisições PUT

Linha 01: Configuramos o método Put para receber um parâmetro do tipo inteiro;

Linhas 06 e 07: Após localizar o registro desejado, alteramos seu status para “modificado” e salvamos as alterações.

Para testar esse método, devemos preencher a propriedade Nome no Postman e, além disso, informar o id na URL, como mostra a Figura 3.


Figura 3. Enviando requisição PUT

Após efetuar essa alteração, podemos enviar uma requisição GET e assim confirmar se os dados foram modificados.

Passo 6: Excluir registros

Para concluir as operações de CRUD, implementaremos agora o método de exclusão, conforme demonstra a Listagem 6.


  01 Delete["/{id:int}"] = parameters =>
  02 {
  03  Filmes filme = this.Bind<Filmes>();
  04  filme.Id = parameters.id;
  05  _contexto.Entry(filme).State = EntityState.Deleted;
  06  _contexto.SaveChanges();
  07
  08  return HttpStatusCode.OK;
  09 };
  
Listagem 6. Método para tratar requisições DELETE

Linha 1: Declaramos o método Delete, que receberá um id como parâmetro;

Linhas 05 e 06: Modificamos o estado do objeto selecionado para “excluído” e salvamos as alterações.

No Postman, para testar esse novo método, basta alterar o verbo para DELETE e informar o id na URL, como em: /filmes/3, sendo 3 o id do filme a ser excluído. Em seguida, podemos enviar novamente uma requisição GET e verificar os registros retornados.