.NET

3 jul, 2017

ASP.NET Core: utilizando compressão em APIs REST

Publicidade

O objetivo deste artigo é demonstrar o uso do middleware de compressão de respostas em APIs REST criadas com o ASP.NET Core.

Introdução

A performance é uma preocupação central em muitas soluções Web, com diversas práticas fornecendo meios para a obtenção de melhores resultados em quesitos como responsividade e quantidade de dados trafegados. As APIs REST não fogem a esta regra, sendo comum em estruturas deste tipo o uso de técnicas de compressão, a fim de reduzir o volume das informações produzidas.

No caso específico do ASP.NET Core, esta plataforma conta com um middleware que simplifica o processo de compressão dos dados a serem retornados por uma aplicação Web. As próximas seções trazem um exemplo de uso deste recurso, a partir da implementação e monitoramento dos dados gerados por uma API REST.

Implementando a aplicação de exemplo

Inicialmente, será criado um projeto do tipo ASP.NET Core Web Application (.NET Core) chamado ExemploCompressao:

Selecione na sequência a versão 1.1 e a opção Web API em ASP.NET Core 1.1 Templates:

Como próximo passo, implemente uma classe chamada Produto, a qual representará os itens comercializados por uma empresa fictícia:

namespace ExemploCompressao
{
    public class Produto
    {
        public string CodProduto;
        public string NomeProduto;
        public double Preco;
    }
}

A classe ProdutosController receberá solicitações de consulta a produtos, devolvendo como resultado uma lista “fake” formada por 100 itens:

using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;

namespace ExemploCompressao.Controllers
{
    [Route("api/[controller]")]
    public class ProdutosController : Controller
    {
        [HttpGet]
        public IEnumerable<Produto> Get()
        {
            List<Produto> produtos = new List<Produto>();

            Produto prod;
            for (int i = 1; i <= 100; i++)
            {
                prod = new Produto();
                prod.CodProduto = i.ToString("0000");
                prod.NomeProduto = string.Format("PRODUTO {0:0000}", i);
                prod.Preco = i / 10.0;

                produtos.Add(prod);
            }

            return produtos;
        }
    }
}

Para os testes desta aplicação de exemplo, será empregado o Fiddler, utilitário gratuito que possibilita o monitoramento de solicitações HTTP enviadas a APIs REST.

Uma requisição será então enviada a ProdutosControllers via browser, produzindo um resultado similar ao da imagem a seguir:

Na próxima figura é possível observar detalhes da resposta gerada, incluindo o tamanho da mesma (6.362 bytes):

Ativando o middleware de compressão

O middleware de compressão de respostas integra o package Microsoft.AspNetCore.ResponseCompression, o qual encontra-se disponível no NuGet:

Para ativar o uso da compactação, será necessário realizar as seguintes modificações na classe Startup:

  • Acionar o método genérico Configure em ConfigureServices, informando o tipo GzipCompressionProviderOptions (namespace Microsoft.AspNetCore.ResponseCompression) e a opção Optimal para CompressionLevel (namespace System.IO.Compression). Este ajuste fará com que a compressão seja otimizada, por mais que este processo leve um pouco mais de tempo para sua conclusão (outros valores possíveis para o enum CompressionLevel são Fastest e NoCompression);
  • Ainda em ConfigureServices invocar o método AddResponseCompression, definindo o tipo GzipCompressionProvider como o provider para a compactação no formato GZIP;
  • Já na operação Configure, acionar o método UseResponseCompression, a fim de ativar o middleware para compressão de respostas.
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System.IO.Compression;
using Microsoft.AspNetCore.ResponseCompression;

namespace ExemploCompressao
{
    public class Startup
    {
        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile(quot;appsettings.{env.EnvironmentName}.json", optional: true)
                .AddEnvironmentVariables();
            Configuration = builder.Build();
        }

        public IConfigurationRoot Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();

            services.Configure<GzipCompressionProviderOptions>(
                options => options.Level = CompressionLevel.Optimal);
            services.AddResponseCompression(options =>
            {
                options.Providers.Add<GzipCompressionProvider>();
            });
        }

        public void Configure(
            IApplicationBuilder app,
            IHostingEnvironment env,
            ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            app.UseResponseCompression();

            app.UseMvc();
        }
    }
}

Após um novo teste via browser, será possível observar no Fiddler que as alterações surtiram efeito:

  • O tamanho da resposta foi reduzido para 772 bytes;
  • Já no atributo Content-Encoding do Header foi especificado o valor gzip, indicando o padrão de compactação utilizado pela API REST.

Conclusão

Este artigo procurou enfatizar como é simples o uso de técnicas de compressão em aplicações baseadas no ASP.NET Core. Ativar o middleware disponibilizado através do package Microsoft.AspNetCore.ResponseCompression requer esforços mínimos em termos de configuração, tendo como resultado direto um menor volume de dados trafegados.