.NET

3 nov, 2016

Criando e consumindo uma Web API (C#) – Parte 01

Publicidade

Neste artigo, vou mostrar criar uma Web API e como consumir o serviço REST criado sobre a plataforma .NET usando a linguagem C#.

A ASP .NET Web API é um framework para construir serviços HTTP sobre a plataforma .Net.  Uma Web API pode ser vista como um conjunto de serviços expostos via web (HTTP) com o objetivo de integrar sua aplicação a diversos tipos de clientes (navegadores, tablets, smartphones, etc.) que queiram usar os serviços.

Esses serviços são usados como requisições HTTP e retornam uma resposta em um formato específico como XML, JSON, ou em um formato que você pode definir. (JSON e´ padrão). Essa resposta pode ser uma informação de  um repositório de dados, o retorno de uma operação, etc.

O cliente pode ser uma página web (Javascript com Ajax, CSS e HTML ), uma aplicação desktop, uma aplicação mobile, etc. Como exemplos de Web API podemos citar as Web APIs do Facebook e Twitter.

ASP .Net Web API foi lançada com o ASP.NET MVC 4 e já esta instalada no VS 2012 , VS 2013 e VS 2015.

Usando API Web ASP.NET podemos criar serviços não baseados em SOAP, como XML ou sequências JSON de caracteres simples, ou ainda em um formato definido. Com as seguintes vantagens:

  • Criar serviços usando recursos do HTTP;
  • Expor serviços a uma gama de clientes como navegadores, dispositivos móveis, smartphones, tables, etc;
  • Funcionar usando verbos HTTP padrão, como GET, POST, PUT, DELETE, etc., para todas as operações de CRUD;
  • Dar suporte completo para roteamento;
  • Dar Respostas no formato JSON ou XML usando MediaTypeFormatter;
  • Capacidade de ser hospedado no IIS, bem como fora do IIS;
  • Suporte a Model Binding e validação;Suport
  • e ao protocolo OData;

Agora chega de teoria e vamos partir para a prática, criando uma Web API que vai expor serviços para atualizar informações de Produtos.

Recursos usados: Visual Studio Community 2015 (baixe e use a versão Community 2015 do VS ela é grátis e é equivalente a versão Professional).

Criando a Web API para expor os serviços sobre Produtos

Abra o VS Community 2015 e clique em New Project;

Selecione a linguagem Visual C# ->ASP .NET Web Application;

Informe o nome WebApi2_Produtos e clique no botão OK;

webapi_cons11

A seguir selecione o template Web API, sem autenticação nem hospedagem na nuvem e clique em OK;

webapi_cons12

Definindo o modelo de domínio e o Repositório de Produtos na pasta Models

Vamos definir o nosso modelo de domínio representando pela classe Produtos e a seguir criar um repositório de produtos.

A criação de um repositório em nosso projeto nos ajudará a centralizar a lógica de acesso aos dados e também vai desacoplar a nossa aplicação da fonte de dados ou ferramenta ORM que porventura venhamos a utilizar.

Vamos criar na pasta Models a classe Produto.cs que será nosso modelo de domínio.

Clique com o botão direito sobre a pasta Models e a seguir em Add Class.

Informe o nome Produto.cs e inclua o seguinte código nesta classe:

 public class Produto
    {
        public int Id { get; set; }
        public string Nome { get; set; }
        public string Categoria { get; set; }
        public decimal Preco { get; set; }
    }

A seguir inclua uma interface chamada IProdutoRepositorio.cs na mesma pasta com o seguinte código:

 public interface IProdutoRepositorio
 {
        IEnumerable<Produto> GetAll();
        Produto Get(int id);
        Produto Add(Produto item);
        void Remove(int id);
        bool Update(Produto item);
 }

Na interface definimos os métodos que deverá ser implementados.

Agora vamos criar a classe ProdutoRepositorio.cs na mesma pasta que vai implementar essa interface.

using System;
using System.Collections.Generic;

namespace WebApi2_Produtos.Models
{
    public class ProdutoRepositorio : IProdutoRepositorio
    {
        private List<Produto> produtos = new List<Produto>();
        private int _nextId = 1;

        public ProdutoRepositorio()
        {
            Add(new Produto { Nome = "Guaraná Antartica", Categoria = "Refrigerantes", Preco = 4.59M });
            Add(new Produto { Nome = "Suco de Laranja Prats", Categoria = "Sucos", Preco = 5.75M });
            Add(new Produto { Nome = "Mostarda Hammer", Categoria = "Condimentos", Preco = 3.90M });
            Add(new Produto { Nome = "Molho de Tomate Cepera", Categoria = "Condimentos", Preco = 2.99M });
            Add(new Produto { Nome = "Suco de Uva Aurora", Categoria = "Sucos", Preco = 6.50M });
            Add(new Produto { Nome = "Pepsi-Cola", Categoria = "Refrigerantes", Preco = 4.25M });
        }

        public Produto Add(Produto item)
        {
            if(item == null)
            {
                throw new ArgumentNullException("item");
            }
            item.Id = _nextId++;
            produtos.Add(item);
            return item;
        }

        public Produto Get(int id)
        {
            return produtos.Find(p => p.Id == id);
        }

        public IEnumerable<Produto> GetAll()
        {
            return produtos;
        }

        public void Remove(int id)
        {
            produtos.RemoveAll(p => p.Id == id);
        }

        public bool Update(Produto item)
        {
            if( item == null)
            {
                throw new ArgumentNullException("item");
            }

            int index = produtos.FindIndex(p => p.Id == item.Id);

            if(index == -1)
            {
                return false;
            }
            produtos.RemoveAt(index);
            produtos.Add(item);
            return true;
        }
    }
}

Nesta classe implementamos uma lista de produtos em memória incluindo alguns produtos e definimos os métodos para obter produtos, atualizar, remover e atualizar os produtos.

Definindo a nossa Web API ProdutosController na pasta Controllers

Uma Web API fornece toda infraestrutura para o desenvolvimento dos serviços, faz a escolha do método a ser executado, converte as mensagens em parâmetros e os tipos adequados, aplica filtros, etc.

Cada requisição por padrão terá como alvo um método dentro desta classe que processa e retorna o resultado.

Clique na pasta Controllers com o botão direito do mouse e a seguir em Add -> Controller;

Selecione o Scaffold : Web API 2 Controller Empty e clique no botão Add;

webapi_cons13

Digite o nome ProdutosController e clique no botão Add;

webapi_cons14

A seguir inclua o código abaixo neste controlador:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using WebApi2_Produtos.Models;

namespace WebApi2_Produtos.Controllers
{
    public class ProdutosController : ApiController
    {
        static readonly IProdutoRepositorio repositorio = new ProdutoRepositorio();

        public IEnumerable<Produto> GetAllProdutos()
        {
            return repositorio.GetAll();
        }

        public Produto GetProduto(int id)
        {
            Produto item = repositorio.Get(id);
            if (item == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            return item;
        }

        public IEnumerable<Produto> GetProdutosPorCategoria(string categoria)
        {
            return repositorio.GetAll().Where(
                p => string.Equals(p.Categoria, categoria, StringComparison.OrdinalIgnoreCase));
        }

        public HttpResponseMessage PostProduto(Produto item)
        {
            item = repositorio.Add(item);
            var response = Request.CreateResponse<Produto>(HttpStatusCode.Created, item);

            string uri = Url.Link("DefaultApi", new { id = item.Id });
            response.Headers.Location = new Uri(uri);
            return response;
        }

        public void PutProduto(int id, Produto produto)
        {
            produto.Id = id;
            if (!repositorio.Update(produto))
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
        }

        public void DeleteProduto(int id)
        {
            Produto item = repositorio.Get(id);

            if (item == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

            repositorio.Remove(id);
        }
    }
}

Neste código estamos usando o nosso repositório definido pela classe ProdutoRepositorio para implementar a nossa Web API 2 expondo os seguintes serviços:

  • GetAllProdutos – retorna todos os produtos;
  • GetProduto – retorna um produto;
  • GetProdutosPorCategoria – retorna os produtos por categoria;
  • PostProduto – inclui um novo produto;
  • PutProduto – altera um produto;
  • DeleteProduto – exclui um produto;

Observe que os nomes dos métodos do controlador ProdutosController iniciam com o nome dos verbos HTTP (GET, POST, PUT e DELETE) isso ajuda a ASP .NET a mapear a requisição do cliente para os métodos do controller (convenção).

Podemos também usar atributos HttpGetAttribute, HttpPostAttribute, HttpPutAttribute, etc, ou ainda usar o atributo ActionNameAttribute e usar uma convenção de nomenclatura para escrita e outra para publicação.

Feito isso já podemos testar o nosso serviço REST exposto pela Web API.  Lembrando que o roteamento padrão definido no arquivo WebApiConfig da pasta App_Start (mostrado abaixo) indica a rota padrão definida em routeTemplate como:

  • a literal: api (este literal é usado para evitar conflitos com o mapeamento MVC)
  • o nome do controlador: produtos
  • e o id (opcional)
 public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            var formatters = GlobalConfiguration.Configuration.Formatters;
            formatters.Remove(formatters.XmlFormatter);
        }
    }

O trecho de código abaixo foi incluído por mim para forçar o envio da resposta no formato JSON.

            var formatters = GlobalConfiguration.Configuration.Formatters;
            formatters.Remove(formatters.XmlFormatter);

Executando o projeto iremos obter a exibição da página da aplicação MVC na URL: localhost:53557/

1- Digitando: api/produtos, obtemos todos os produtos:

webapi_cons15

2- Digitando: api/produtos/4 , obtemos o produto com id igual a 4:

webapi_cons16

3- Digitando: api/produtos/?categoria=Sucos , obtemos os produtos desta categoria:

webapi_cons17

Dessa forma, nossa Web API está pronta para ser consumida e vamos fazer isso na segunda parte do artigo.

Pegue o projeto da Web API completo aqui: WebApi2_Produtos.zip (sem as referências)