.NET

20 fev, 2017

ASP.NET Core: criando uma API REST com EF Core, PostgreSQL e VS Code for Linux

Publicidade

Veja neste artigo como implementar uma API REST em Linux, utilizando para isto o ASP.NET Core 1.1, o Entity Framework, o Visual Studio Code e uma base de dados do PostgreSQL.

E por falar em ASP.NET Core, deixo aqui um convite. No dia 22/02 (quarta) teremos um bate-papo online (hangout) no Canal .NET sobre o .NET Core e o .NET Standard, às 22h00 – horário de Brasília. Será uma ótima oportunidade para todos aqueles interessados em conhecer mais sobre as novidades e o futuro da plataforma .NET.

Para efetuar sua inscrição acesse este link, a transmissão será via YouTube em um link a ser divulgado futuramente.

Introdução

Uma das soluções de mapeamento objeto-relacional (ORM) mais populares entre desenvolvedores .NET, o Entity Framework também conta agora com uma versão multiplataforma baseada no .NET Core: trata-se do Entity Framework Core, um projeto open source mantido pelo mesmo time responsável pelo ASP.NET Core.

Além do óbvio suporte ao SQL Server, merece ser destacado ainda sobre esta nova versão do Entity Framework:

  • A possibilidade de armazenamento de dados em memória. Este recurso pode se revelar como extremamente útil na implementação de provas de conceito, já que descarta a obrigatoriedade do uso de uma base relacional;
  • Outras tecnologias de bancos de dados como PostgreSQL, MySQL e SQLite também contam com providers para uso do Entity Framework Core.

As próximas seções trazem um exemplo prático de implementação de uma API REST para consulta de cotações de moedas estrangeiras. A fim de cumprir este objetivo serão empregados o Entity Framework Core como solução ORM e o ASP.NET Core como plataforma Web.

Tecnologias a serem utilizadas

A API REST detalhada neste artigo fará uso do ASP.NET Core 1.1 e do Entity Framework Core. Para isto, criaremos ainda uma base com o PostgreSQL, além de utilizar o Visual Studio Code 1.9 e o Yeoman como ferramentas para a implementação da aplicação.

O ambiente de desenvolvimento aqui descrito foi montado em uma máquina virtual baseada na versão 16.04 do Ubuntu Desktop. Para maiores detalhes sobre como configurar os recursos necessários, acesse este link.

Criando a base para testes

Para a geração da base PostgreSQL de testes será utilizado o ElephantSQL, um serviço de banco de dados na nuvem que integra o IBM Bluemix. Para maiores informações sobre esta solução, consulte este link: PostgreSQL database hosting with ElephantSQL on Bluemix

O endereço do portal para utilização do IBM Bluemix é o seguinte: https://console.ng.bluemix.net/.

No portal do IBM Bluemix serão listados os serviços ativados para uma conta dentro desta plataforma:

Clicando no item criado para uso do ElephantSQL, aparecerá um link de acesso a um painel, o qual permitirá a manipulação de bancos de dados criados com este serviço:

Na seção Details serão exibidas as configurações para acesso à base de dados que se encontra na nuvem:

Uma tabela de cotações deverá ser criada, assim como carregados para efeitos de testes alguns dados envolvendo os valores de moedas estrangeiras. Na próxima listagem estão as instruções que possibilitarão isso:

CREATE TABLE "Cotacoes"(
    "Sigla" char(3) NOT NULL,
    "NomeMoeda" varchar(30) NOT NULL,
    "UltimaCotacao" timestamp NOT NULL,
    "Valor" numeric (18,4) NOT NULL,
    CONSTRAINT "PK_Cotacoes" PRIMARY KEY ("Sigla")
);

INSERT INTO "Cotacoes"
           ("Sigla"
           ,"NomeMoeda"
           ,"UltimaCotacao"
           ,"Valor")
     VALUES
           ('USD'
           ,'Dólar norte-americano'
           ,'2017-02-10 16:59'
           ,3.1092);

INSERT INTO "Cotacoes"
           ("Sigla"
           ,"NomeMoeda"
           ,"UltimaCotacao"
           ,"Valor")
     VALUES
           ('EUR'
           ,'Euro'
           ,'2017-02-10 16:59'
           ,3.3177);

INSERT INTO "Cotacoes"
           ("Sigla"
           ,"NomeMoeda"
           ,"UltimaCotacao"
           ,"Valor")
     VALUES
           ('LIB'
           ,'Libra esterlina'
           ,'2017-02-10 16:59'
           ,3.8944);

Estes comandos poderão ser executados na seção Browser, como indicado na imagem a seguir:

Consultas também podem ser realizadas através desta funcionalidade:

Implementando a aplicação

Para iniciar a criação do projeto de testes, execute a seguinte linha de comando em uma janela do Terminal no Ubuntu: yo aspnet.

O Yeoman apresentará, então, uma lista de templates; selecione a opção Web API Application e confirmar:

E encerrar este processo informando como nome da aplicação, o valor APICotacoes:

Um aviso similar ao da próxima janela aparecerá, caso o projeto seja criado com sucesso:

Acessar agora o diretório APICotacoes, executando o comando a seguir para restaurar as dependências da aplicação: dotnet restore.

O resultado desta ação pode ser visualizado na próxima imagem:

Como próximo passo, será implementada uma classe chamada Cotacao, cujas instâncias conterão os dados relativos a uma cotação de moeda estrangeira. Criar para isto um arquivo chamado Cotacao.cs via Yeoman, através da seguinte linha de comando: yo aspnet:class Cotacao.cs.

A seguir está a confirmação de que o arquivo Cotacao.cs foi gerado:

Para ter acesso ao conteúdo do projeto no Visual Studio Code, digite no Terminal, a partir do diretório APICotacoes, o seguinte comando: code.

O Visual Studio Code será, então, exibido. Clique no painel esquerdo deste utilitário sobre o arquivo Cotacao.cs, de forma a exibir o conteúdo da classe correspondente:

Na próxima listagem está o código que define o tipo Cotacao:

using System;

namespace APICotacoes
{
    public class Cotacao
    {
        public string Sigla { get; set; }
        public string NomeMoeda { get; set; }
        public DateTime UltimaCotacao { get; set; }
        public decimal Valor { get; set; }
    }
}

Editar na sequência o arquivo project.json, a fim de incluir o provider do Entity Framework Core para uso do PostgreSQL (versão 1.1.0 do package Npgsql.EntityFrameworkCore.PostgreSQL):

Salve, então, as alterações realizadas em project.json, clicando para isto na opção Restore com o intuito de efetuar o download da nova dependência adicionada ao projeto:

Uma string de conexão chamada BaseCotacoes deverá ser adicionada ao arquivo appSettings.json:

{
  "ConnectionStrings": {
    "BaseCotacoes": "Host=?;Port=5432;Pooling=true;Database=?;User Id=?;Password=?;"
  },
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  }
}

Uma classe de contexto chamada CotacoesContext também será criada, de forma a possibilitar a consulta aos dados dos quais a API REST de cotações depende. Executar, então, a seguinte linha de comando: yo aspnet:class CotacoesContext.cs.

O resultado desta ação pode ser visualizado na próxima imagem:

O tipo CotacoesContext herda da classe básica DbContext (namespace Microsoft.EntityFrameworkCore), sendo possível observar na implementação do mesmo:

  • Uma propriedade baseada na classe genérica DbSet (namespace Microsoft.EntityFrameworkCore), a qual será utilizada no acesso a dados pertencentes à tabela de cotações;
  • Um construtor que receberá como parâmetro uma instância do tipo genérico DbContextOptions (namespace Microsoft.EntityFrameworkCore), com este último contendo as configurações para acesso à base criada no PostgreSQL;
  • O método sobrecarregado OnModelCreating espera como parâmetro uma referência da classe ModelBuilder (namespace Microsoft.EntityFrameworkCore), que será usada para especificar a chave primária da tabela contendo cotações de moedas estrangeiras.
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.EntityFrameworkCore;

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

        public IConfigurationRoot Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
           services.AddEntityFrameworkNpgsql()
                .AddDbContext<CotacoesContext>(
                    options => options.UseNpgsql(
                        Configuration.GetConnectionString("BaseCotacoes")));

            services.AddMvc();
        }

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

            app.UseMvc();
        }
    }
}

Por fim, um novo Controller chamado CotacoesController deverá ser criado via Yeoman. Acessar para isto o diretório Controllers, executando a seguinte linha de comando: yo aspnet:webapicontroller CotacoesController.cs.

Esta instrução fará com que seja gerado um arquivo chamado CotacoesController.cs:

Remover também o arquivo ValuesController.cs (criado automaticamente pelo Yeoman) por meio do comando indicado a seguir: rm ValuesController.cs.

O Controller CotacoesController contém a implementação da API de consulta a cotações de moedas estrangeiras. O código esperado para este tipo foi detalhado na próxima listagem, sendo possível observar no mesmo:

  • A classe CotacoesController herda do tipo básico Controller (namespace Microsoft.AspNetCore.Mvc), o qual contém os recursos básicos para a definição de Controllers tanto em Web API, quanto em projetos MVC. Em versões anteriores do framework Web API, um serviço deveria herdar da classe ApiController (namespace System.Web.Http), a qual representava a implementação padrão para estruturas deste tipo;
  • Percebe-se ainda a ausência de referências ao namespace System.Web, o qual não está mais presente em virtude do processo de completa reformulação que aconteceu no novo ASP.NET;
  • O atributo Route foi associado à classe CotacoesController, de maneira que chamadas à API de cotações utilizem como caminho-base o valor /api/cotacoes;
  • O parâmetro indicado em HttpGet determina que as solicitações a serem tratadas pelo método Get tenham como endereço o valor /api/cotacoes/{id}, em que {id} representa a código/sigla de uma moeda estrangeira. O retorno desta operação será uma instância do tipo Cotacao, na qual estarão dados como a descrição da moeda e sua sigla, a data/hora da última cotação e o valor correspondente;
  • Na operação Get foi declarado também um parâmetro do tipo CotacoesContext. Esta referência que possibilitará o acesso à base PostgreSQL na nuvem foi marcada com o atributo FromServices, o que indica que a mesma será resolvida via mecanismo de injeção de dependências do ASP.NET Core.
using System.Linq;
using Microsoft.AspNetCore.Mvc;

namespace APICotacoes.Controllers
{
    [Route("api/[controller]")]
    public class CotacoesController : Controller
    {
        [HttpGet("{id}")]
        public Cotacao Get(
            [FromServices]CotacoesContext context,
            string id)
        {
            return context.Cotacoes
                .Where(c => c.Sigla == id)
                .FirstOrDefault();
        }
    }
}

Testes

Para iniciar a execução da aplicação a partir do Visual Studio Code, acione o ícone Debug (destacado em vermelho):

Assegure-se, então, de que foi selecionada a opção .NET Core Launch (web), clicando em seguida no botão Start Debugging (representado por um triângulo verde):

Na imagem a seguir, é possível observar o retorno produzido pela API, ao se informar como URL para testes o endereço http://localhost:5000/api/cotacoes/USD (por default aplicações criadas via Yeoman utilizam a porta 5000):

Para consultar informações sobre o euro, utilize a URL http://localhost:5000/api/cotacoes/EUR:

Já o endereço http://localhost:5000/api/cotacoes/LIB permitirá que se obtenha o valor da libra esterlina:

Conclusão

Além de suportar nativamente o SQL Server, o Entity Framework Core pode ser utilizado com outros bancos como o PostgreSQL sem maiores dificuldades. Este artigo demonstrou justamente isto, empregando para tanto o provider disponibilizado especificamente para o PostgreSQL.

Embora a API de cotações tenha sido desenvolvida em Linux com o Visual Studio Code, este processo em nada difere quando realizado em Windows ou Mac. Tudo isto é possível graças ao caráter multiplataforma do .NET Core e tecnologias relacionadas, o que certamente contribuirá para uma presença cada vez maior do ASP.NET em cenários nos quais o mesmo não se fazia presente.

E para finalizar, não deixe de acompanhar também a playlist com vídeos sobre ASP.NET Core produzidos pelo Canal .NET: