Escolha uma Página

Fala time, bom ou não?

Quando me lembro do meu início no mundo do desenvolvimento de Software, logo penso nas estratégias que utilizei para aprender a lógica de programação, linguagens, etc. Uma das técnicas que mais utilizava era em formato de desafio a mim mesmo de acordo com o contexto em que vivia. Por exemplo, meu irmão estava estudando matemática, então, para ajudá-lo a conferir se os seus exercícios estavam corretos, me lancei um desafio de produzir um software com o objetivo de implementar a matéria na qual meu irmão estava aprendendo. Isso era ótimo e me fazia aprender várias técnicas.

Ainda neste raciocínio, um amigo me pediu opinião sobre ferramentas de desenvolvimento, fora do Windows, para as tecnologias Microsoft. Falei sobre o ótimo VS Code. Como ele está acostumado com o Visual Studio, me pediu um exemplo de projeto, uma WebAPI, fazendo conexões em um banco de dados MySQL. Este artigo consiste em demonstrar, passo a passo, como produzir esta api e muito mais!

Pre-requisitos

  • Visual Studio Code
  • .Net Core 2.1 sdk.

Criação do projeto

A criação de um projeto no Visual Studio é uma tarefa bem simples. Tudo funciona com base em templates, de forma visual selecionamos o projetos, definimos um nome e clicamos em OK. Pronto! Projeto criado. E como funciona no Visual Studio Code? É ai que está a beleza de tudo. O Visual Studio Code é um editor de código e a responsabilidade de criação do projeto fica por conta do CLI do dotnet, instalado juntamente com o SDK do .Net Core.

O primeiro passo é definir uma pasta em seu computador, na qual o seu projeto será criado. Após definida a pasta, basta abrir o prompt de comando ou terminal e digitar o seguinte comando:

dotnet new sln <Enter>

Uma solution será criada com o mesmo nome da pasta onde o comando foi executado. O próximo passo é a criação do projeto. Digite o comando:

dotnet new <enter>

Uma lista de projetos será exibida:

Esta lista exibe os templates de projetos disponíveis para criação. É parecido com o que já existe no Visual Studio, porém pelo terminal. Para escolher o projeto a ser criado, basta executar o mesmo comando, dotnet new, com o short name do projeto desejado, em nosso caso, webapi. Execute novamente o comando:

dotnet new webapi <enter>

A estrutuda do projeto foi criada. Agora é hora de adicionar o projeto na solution:

dotnet sln add <NomeDoProjeto>.csproj <enter>

Observação: A adição de uma solution e do projeto nesta, é para manter a compatibilidade. Se você desejar trabalhar com o Visual Studio, no Windows, no mesmo projeto, basta abrir a solution.

Projeto criado, agora vamos adicionar alguns recursos para incrementar nossa api.

Adicionando pacotes Nuget

Através do CLI do dotnet também é possível trabalhar com o gerenciador de pacotes Nuget. Iremos adicionar 2 pacotes, Swagger(para documentação da API), MySQLConnector(Para conectar no banco de dados) e o Dapper (para facilitar o mapeamento do resultado da consulta no banco de dados). Na raiz da pasta onde encontra-se o projeto, digite os seguintes comandos para adicionar os pacotes:

dotnet add package MySqlConnector --version 0.43.0 <enter>
dotnet add package Swashbuckle.AspNetCore --version 3.0.0 <enter>
dotnet add package Dapper --version 1.50.5 <enter>

Projeto pronto, pacotes adicionados, agora é mão na massa.

Criação da Webapi

A tarefa mais simples agora é abrir o editor do VS Code a partir do diretório de projetos. Para isso, execute o seguinte comando no terminal:

code . <enter>

Com o VS Code aberto, é hora de criar alguns arquivos e pastas na API conforme a imagem abaixo:

.
├── Controllers
│   └── PessoaController.cs
└── Model
│   └── Pessoa.cs
└── Repository
    └── IPessoaRepository.cs
    └── PessoaRepository.cs

Na estrutura acima não estão sendo listados arquivos e pastas padrões, criados pelo template da API. Apenas o que será novo e que será trabalhado.

Detalhes dos arquivos

namespace ApiMySql.Model
{
    public class Pessoa
    {
        public int Codigo { get; set; }
        
        public string Nome { get; set; }

        public string Endereco { get; set; }
    }
}

Esta classe irá representar um registo de Pessoas, do banco de dados.

using System.Collections.Generic;
using ApiMySql.Model;

namespace ApiMySql.Repository
{
    public interface IPessoaRepository
    {
        IEnumerable<Pessoa> GetAll();
    }
}

Interface de repositório de pessoa. Possui apenas uma assinatura de método, GetAll.

using System.Collections.Generic;
using ApiMySql.Model;
using MySql.Data.MySqlClient;
using Dapper;

namespace ApiMySql.Repository
{
    public class PessoaRepository : IPessoaRepository
    {
        private readonly string _connectionString;

        public PessoaRepository(string connectionString)
        {
            _connectionString = connectionString;   // Injetando a string de conexão no construtor da classe
        }

        public IEnumerable<Pessoa> GetAll()
        {
            using(MySqlConnection connection = new MySqlConnection(_connectionString))
            {
                return connection.Query<Pessoa>("SELECT Codigo, Nome, Endereco FROM Pessoa ORDER BY Nome ASC");
            }
        }
    }
}

Esta é a implementação do contrato IPessoaRepository.cs. O método GetAll apenas cria uma conexão com o banco de dados, através da classe MySqlConnection, provida pelo nuget package MySqlConnector. Além disso, o método Query, do objeto connection, é, na verdade, um Extension Method provido pelo namesmace Dapper. Com esta abordagem é mais fácil fazer uma consulta na base de dados e retornar, como resultado, uma lisa de objetos pessoa. No exemplo, a consulta é feita em um banco de dados contendo uma tabela chamada Pessoa com os campos Codigo, Nome e Endereco.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ApiMySql.Repository;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Swashbuckle.AspNetCore.Swagger;

namespace ApiMySql
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
            });

            services.AddScoped<IPessoaRepository>(factory => {
                    return new PessoaRepository(Configuration.GetConnectionString("MySqlDbConnection"));
            });
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }

            // Configurações do Swagger no pipiline de execução da aplicação.
            app.UseSwagger();

            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "Minha API .Net Core e VS Code");
            });

            app.UseMvc();
        }
    }
}

Além das configurações necessárias para que o Swagger funcione(Linhas: 31 a 34 e 53 a 58) também é necessário adicionar no contexto de injeção de dependência a resolução da interface IPessoaRepository e “dizer” ao PessoaRepository qual é a string de conexão do banco de dados. Esta configuração é feita entre as linhas 36 e 38, que, basicamente, pode-se ler da seguinte forma:

Adicione no contexto de injeção de dependência um contrato chamado IPessoaRepository e onde houver a dependência deste, criar uma instância de PessoaRepository e passando em seu construtor a string de conexão com a base de dados MySql, obtida do arquivo appsettings.json.

Com isso, a classe PessoaController terá a dependência do contrato, definida no construtor, IPessoaController resolvida.

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "ConnectionStrings": {
    "MySqlDbConnection": "server=localhost;database=MyFirstAPI;user id=root;password=p@ssw0rd"
  },
  "AllowedHosts": "*"
}

A string de conexão com o banco de dados foi definida no arquivo appsettings.json e é obtida na classe Startup.cs através do código Configuration.GetConnectionString(“MySqlDbConnection”). Espera-se, neste exemplo, que exista uma tabela chamada Pessoa com os campos Codigo, Nome e Endereco.

using ApiMySql.Model;
using ApiMySql.Repository;
using Microsoft.AspNetCore.Mvc;
using System.Linq;

namespace ApiMySql.Controller
{
    [ApiController]
    [Route("/api/[controller]")]
    public class PessoaController : ControllerBase
    {
        private readonly IPessoaRepository _pessoaRepository;

        public PessoaController(IPessoaRepository pessoaRepository)
        {
            _pessoaRepository = pessoaRepository;
        }

        [HttpGet]
        [Produces(typeof(Pessoa))]
        public IActionResult Get()
        {
            var pessoas = _pessoaRepository.GetAll();

            if (pessoas.Count() == 0)
                return NoContent();

            return Ok(pessoas);
        }
    }
}

Nesta classe apenas existe o método Get, que retorna todas as pessoas cadastradas na tabela Pessoa do banco de dados MySql. Observe que o contrato IPessoaRepository é uma dependência da classe PessoaController. Sendo assim, quando o pipeline de execucão do ASP.net Core criar uma instância dessa classe, a dependência do contrato será automaticamente resolvida, conforme configurado no arquivo Startup.cs.

O método Get retorna OK (HttpStatusCode = 200) se houverem pessoas no retorno do repositório ou No Content(HttpStatusCode = 204).


Com toda a aplicação desenvolvida é hora de testar. Execute o seguinte comando no terminal, no diretório onde encontra-se o arquivo .csproj:

dotnet run <enter>

Instalamos o pacote do swagger para prover uma documentação na API. Sua configuração é bem simples. Acesse o passo a passo no seguinte link: https://docs.microsoft.com/en-us/aspnet/core/tutorials/getting-started-with-swashbuckle?view=aspnetcore-2.1&tabs=visual-studio%2Cvisual-studio-xml

A seguinte mensagem deve aparecer:

Isso quer dizer que a api está sendo executada no endereço especificado. Pelo browser, acesse http://localhost:5000/swagger.

Acessando a página do Swagger, basta clicar em “/api/Pessoa”, em seguira no botão “Try it out”. A consulta será feita no banco de dados e trará todos os registros disponíveis na tabela de Pessoa, conforme definido na cosulta no RepositoryPessoa.

Show demais!

O projeto trouxe vários conceitos importantes, como a utilização do CLI para criação de solutions, projetos e adicionar pacotes Nuget. Além disso, a utilização de Libraries como Swagger, Dapper e MySqlConnector demonstrou as boas práticas que utilizo no desenvolvimento das minhas APIs.

Espero que tenham gostado. Um agradecimento especial ao meu amigo Igor que inspirou este artigo.

Se tem mais alguma dúvida, acesse o repositório no Git com todo o código fonte e instruções: Código Fonte