web-api

Em um post anterior abordei o uso de técnicas de compressão em serviços Web API, empregando um package do NuGet que simplifica em muito este tipo de tarefa. Neste novo artigo a ideia é concluir esta série, através de um exemplo prático que demonstra como o serviço criado pode ser consumido em uma aplicação-cliente.

Consumo o serviço Web API de testes

Para a implementação do projeto descrito neste artigo foram utilizados os seguintes recursos:

  • O Microsoft Visual Studio Community 2015 como IDE de desenvolvimento;
  • O .NET Framework 4.6;
  • O Microsoft ASP.NET MVC 5;
  • O package Microsoft ASP.NET Web API 2.2 Client Libraries;
  • A biblioteca Google Chart Tools (a qual é formada um conjunto de plugins jQuery empregados na geração de tabelas e gráficos).

Um projeto do tipo “ASP.NET Web Application” chamado “TesteConsumoWebAPI” deverá ser criado, como indicado na Imagem 1.

web-api-comprpt2-01
Imagem 1: Criando uma ASP.NET Web Application no Visual Studio 2015

Selecionar então o template “MVC”, desabilitando ainda a utilização de mecanismos de autenticação (Imagem 2).

web-api-comprpt2-02
Imagem 2: Criando um projeto do tipo MVC

Para a instalação do package Microsoft ASP.NET Web API 2.2 Client Libraries acessar o menu “TOOLS” e, em seguida, “NuGet Package Manager” > “Package Manager Console” (Imagem 3).

web-api-comprpt2-03
Imagem 3: Acessando o NuGet Package Manager

Aparecerá neste momento a janela “Package Manager Console” (Imagem 4), na qual deverá ser digitada a seguinte linha de comando:

Install-Package Microsoft.AspNet.WebApi.Client

web-api-comprpt2-04
Imagem 4: O prompt de comandos do NuGet Package Manager

Como ajuste inicial será preciso incluir o endereço do serviço de testes na seção appSetting do arquivo Web.config (Listagem 1).

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>

    ...

    <add key="UrlCatalogoProdutos"
         value="http://localhost:55042/testes/produtos"/>
  </appSettings>

  ...

</configuration>

Listagem 1: Arquivo Web.config

Uma classe chamada “Produto” deverá ser definida para esta aplicação de testes (Listagem 2). Importante destacar que este tipo segue a mesma estrutura dos dados retornos pelo serviço de exemplo, sendo a base para que a resposta obtida possa ser manipulada como uma coleção de objetos convencionais.

namespace TesteConsumoWebAPI.Models
{
    public class Produto
    {
        public string CodProduto { get; set; }
        public string NomeProduto { get; set; }
        public double Preco { get; set; }
    }
}

Listagem 2: Classe Produto

O próximo passo agora será a implementação de um Controller cujas Views associadas consumirão os dados do serviço de testes. Essa estrutura será criada a partir do template “MVC 5 Controller – Empty” (Imagem 5), tendo por nome “ProdutosController” (Imagem 6).

web-api-comprpt2-05
Imagem 5: Criando um novo Controller no Visual Studio

web-api-comprpt2-06
Imagem 6: Definindo o nome de um novo Controller

Na Listagem 3 está a definição da classe ProdutosController. Este Controller conta com as Actions ExemploConsumoDotNet e ExemploConsumojQuery, através das quais será demonstrado como os dados do serviço de testes podem ser consumidos (via código .NET e jQuery, respectivamente). Por mais que tal retorno esteja compactado a fim de otimizar o tráfego de rede, o processo de manipulação de tais informações em nada difere das ações que seriam realizadas para o acesso a uma aplicação Web API convencional.

Quanto ao método que define a Action ExemploConsumoDotNet, é possível destacar:

  • Uma nova instância da classe HttpClient (namespace System.Net.Http) será gerada, de forma a possibilitar a comunicação com o serviço de consulta ao catálogo de produtos;
  • A propriedade DefaultRequestHeaders será configurada para que as requisições solicitem os dados no padrão JSON, recebendo para isto uma instância do tipo MediaTypeWithQualityHeaderValue (namespace System.Net.Http.Headers);
  • Uma solicitação será enviada so serviço de consulta a produtos, a partir da invocação do método GetAsync do objeto client. O resultado desta ação será uma referência do tipo HttpResponseMessage (namespace System.Net.Http);
  • A chamada ao método EnsureSuccessStatusCode de HttpResponseMessage fará com que a mensagem recebida seja validada, lançando uma exceção no caso de um conteúdo inválido;
  • Ao se acionar a operação ReadAsAsync via propriedade Content do objeto response será retornada uma lista com os produtos disponíveis (se não existam problemas com a mensagem retornada). Esta ação demonstra, em linhas gerais, que nenhum tratamento especial é exigido para o consumo de dados previamente comprimidos;
  • Por fim, a lista de produtos obtida será informada como parâmetro ao se invocar o método View.

Já a Action ExemploConsumojQuery associa a URL do serviço de testes ao objeto ViewBag, permitindo assim a utilização deste valor na View em que acontece o acesso aos dados via jQuery.

using System.Collections.Generic;
using System.Web.Mvc;
using System.Configuration;
using System.Net.Http;
using System.Net.Http.Headers;
using TesteConsumoWebAPI.Models;

namespace TesteConsumoWebAPI.Controllers
{
    public class ProdutosController : Controller
    {
        public ActionResult ExemploConsumoDotNet()
        {
            List<Produto> produtos;
            using (var client = new HttpClient())
            {
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(
                    new MediaTypeWithQualityHeaderValue("application/json"));

                HttpResponseMessage response = client.GetAsync(
                    ConfigurationManager.AppSettings["UrlCatalogoProdutos"]).Result;
                response.EnsureSuccessStatusCode();

                produtos = response.Content.ReadAsAsync<List<Produto>>().Result;
            }

            return View(produtos);
        }

        public ActionResult ExemploConsumojQuery()
        {
            ViewBag.UrlCatalogoProdutos =
                ConfigurationManager.AppSettings["UrlCatalogoProdutos"];
            return View();
        }
    }
}

Listagem 3: Classe ProdutosController

Com as Actions já definidas, agora será o momento de implementar a primeira View desta aplicação MVC. Essa estrutura conterá o resultado da execução da Action ExemploConsumoDotNet, podendo ser criada por meio de um clique com o botão direito do mouse sobre o método correspondente dentro do Visual Studio: no menu de atalho apresentado selecionar a opção “Add View…” (Imagem 7).

web-api-comprpt2-07
Imagem 7: Criando uma nova View

Com a janela “Add View” ativa, executar as seguintes ações (conforme descrito na Imagem 8):

  • Selecionar no campo “Template” a opção “List”;
  • Já em “Model Class” deverá ser escolhida a classe Produto;
  • Concluir este processo acionando o botão “Add”.

web-api-comprpt2-08
Imagem 8: Adicionando a View ExemploConsumoDotNet ao projeto

Na Listagem 4 está o código esperado para o arquivo ExemploConsumoDotNet.csthml. Esta View exibirá os dados do catálogo de produtos, os quais foram obtidos a partir de uma chamada ao serviço de testes na classe ProdutosController.

@model IEnumerable<TesteConsumoWebAPI.Models.Produto>

<h2>Catálogo de Produtos (Exemplo de consumo de um serviço Web API em .NET)</h2>

<table class="table">
    <tr>
        <th style="width: 200px;">
            Cód.Produto
        </th>
        <th>
            Nome do Produto
        </th>
        <th style="width: 120px; text-align: right;">
            Preço
        </th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @item.CodProduto
        </td>
        <td>
            @item.NomeProduto
        </td>
        <td style="text-align: right;">
            @item.Preco.ToString("0.00")
        </td>
    </tr>
}

Listagem 4: View ExemploConsumoDotNet.cshtml

Uma nova View associada à Action ExemploConsumojQuery também deverá ser incluída no projeto, como indicado na Imagem 9: selecionar neste útimo caso a opção “Empty (without model)” para a opção “Template”.

web-api-comprpt2-09
Imagem 9: Adicionando a View ExemploConsumojQuery ao projeto

Na Listagem 5 estão as instruções para o arquivo ExemploConsumojQuery.cshtml. Através do uso do Google Chart Tools, esta View irá demonstrar como dados podem ser consumidos a partir de código JavaScript (mais uma vez, não há uma diferenciação entre serviços que utilizem ou não técnicas de compactação):

  • O preenchimento da propriedade cors do objeto support de jQuery com o valor “true” é um dos pré-requisitos, a fim de permitir o envio de chamadas ao serviço de renderização do Google Chart Tools;
  • Na sequência, a invocação do método load a partir do objeto google indicará que uma tabela será gerada para a visualização de dados;
  • A função responsável pera renderização da tabela (gerarVisualizacaoTabelaProdutos) será informada como parâmetro ao método setOnLoadCallback do objeto google.

Quanto à forma como o método gerarVisualizacaoTabelaProdutos foi definido, é possível observar:

  • A criação de um Data Table, através da geração de uma nova instância do tipo google.visualization.DataTable. As colunas da tabela resultante são configuradas por meio do método addColumn (que recebe como parâmetros o tipo e a descrição do campo);
  • Uma chamada via instrução jQuery ao método da aplicação Web API fornecerá os dados do catálogo de produtos. Utilizando o comando $.ajax e uma URL em que consta o endereço de destino (obtido por meio do objeto ViewBag), uma requisição será enviada ao serviço de testes (de forma síncrona, algo indicado por meio do parâmetro async). O resultado deste procedimento será um conjunto de informações no formato JSON;
  • Os dados retornados pela aplicação Web API são transformados então em um array, fazendo uso para isto da instrução $.each (que permite navegar a cada objeto JSON obtido, convertendo as informações que compõem o mesmo para a matriz no formato esperado pelo Data Table);
  • Um objeto do tipo google.visualization.NumberFormat é gerado, com o intuito de se proceder com a formatação de valores monetários;
  • Como último passo a tabela será gerada, utilizando para isso uma instância do tipo google.visualization.Table. O resultado desta ação será renderizado no elemento “divTabelaProdutos”.
<h2>Catálogo de Produtos (Exemplo de consumo de um serviço Web API via jQuery)</h2>
<br />
<div id="divTabelaProdutos">
</div>

@section Scripts {
    @Scripts.Render("http://www.google.com/jsapi")

    <script type="text/javascript">

        jQuery.support.cors = true;

        google.load('visualization', '1', { packages: ['table'] });
        google.setOnLoadCallback(gerarVisualizacaoTabelaProdutos);

        function gerarVisualizacaoTabelaProdutos() {
            var data = new google.visualization.DataTable();
            data.addColumn('string', 'Cód.Produto');
            data.addColumn('string', 'Nome do Produto');
            data.addColumn('number', 'Preço');

            var urlCatalogoProdutos = '@ViewBag.UrlCatalogoProdutos';

            var retornoWS;
            $.ajax(
            {
                type: 'GET',
                url: urlCatalogoProdutos,
                dataType: 'json',
                crossDomain: true,
                async: false,
                success: function (data) {
                    retornoWS = data;
                }
            });

            var dadosProdutos = [];
            $.each(retornoWS, function (i, produto) {
                dadosProdutos.push([
                    produto.CodProduto.toString(),
                    produto.NomeProduto.toString(),
                    parseFloat(produto.Preco)]);
            });
            data.addRows(dadosProdutos);

            var formatter = new google.visualization.NumberFormat(
                {
                    decimalSymbol: ',',
                    groupingSymbol: '.',
                    fractionDigits: 2
                });
            formatter.format(data, 2);

            var controle = new google.visualization.Table(
                document.getElementById('divTabelaProdutos'));
            controle.draw(data, { width: 800 });
        }

    </script>
}

Listagem 5: View ExemploConsumojQuery.cshtml

Testes

Para a realização dos testes descritos nesta seção será necessário que o serviço de consulta ao catálogo de produtos esteja em execução. Esta aplicação pode ser baixada a partir do seguinte link:

https://github.com/renatogroffe/TesteCompressaoWebAPI

Na Imagem 10 está a tela inicial da aplicação TesteConsumoWebAPI, com a execução desta última acontecendo através do Visual Studio.

web-api-comprpt2-10
Imagem 10: Tela inicial da aplicação TesteConsumoWebAPI

Ao acionar o link “Consumindo os dados em .NET” será exibida a listagem de produtos obtida a partir do processamento da Action ExemploConsumoDotNet (Imagem 11).

web-api-comprpt2-11
Imagem 11: Consulta ao catálogo de produtos via código .NET

Já a visualização dos dados manipulados via jQuery acontecerá através do link “Consumindo os dados em jQuery” (Imagem 12).

web-api-comprpt2-12
Imagem 12: Consulta ao catálogo de produtos via código jQuery

Conclusão

Conforme demonstrado ao longo deste artigo, consumir os dados de uma aplicação Web API que faz uso de técnicas de compressão em nada difere do mesmo processo envolvendo um serviço convencional. A adoção deste tipo de prática, desde que bem planejada, pode resultar em ganhos significativos de performance (já que contribui na diminuição do volume de informações trafegadas por uma rede).

Espero que este conteúdo possa ter sido útil.

Até uma próxima oportunidade!

Referências

ASP.NET Web API
http://www.asp.net/web-api

Fontes da solução descrita neste artigo
https://github.com/renatogroffe/TesteConsumoWebAPI

Google Chart Tools
https://developers.google.com/chart/

Microsoft ASP.NET Web API 2.2 Client Libraries
https://www.nuget.org/packages/Microsoft.AspNet.WebApi.Client/

Renato Groffe

Atua como consultor em atividades voltadas ao desenvolvimento de softwares há mais de 13 anos. Bacharel em Sistemas de Informação, com especialização em Engenharia de Software. Microsoft Certified Technology Specialist (Web, WCF, Distributed Applications, ADO.NET, Windows Forms), Microsoft Specialist (HTML5 with JavaScript and CSS3, Developing ASP.NET MVC 4 Web Applications), Oracle Certified Associate (PL/SQL), Sun Certified (SCJP, SCWCD), ITIL Foundation V2, Cobit 4.1 Foundation.

Facebook Google+ 

Comentários

comentarios