ASP .NET Core - Web API com MySQL em um Contêiner Docker - I
Hoje veremos como criar uma Web API ASP.Net Core acessando o MySQL e executar a aplicação em um contêiner Docker. |
Hoje vamos iniciar uma série de 3 artigos que aborda a utilização da criação de contêineres Docker para aplicações ASP .NET Core e para o MySql..
Objetivos e requisitos
Vamos criar uma aplicação ASP .NET Core WEb API para gerenciar informações sobre Produtos como : Id, Name, Description e Price, fazendo um CRUD básico no MySQL e vamos conteinerizar esta API.
Nesta aplicação vamos usar o EF Core e o banco de dados MySQL em um contêiner. Assim teremos dois contêineres : a aplicação Web API que vai acessar o contêiner do banco de dados MySQL.
Os recursos que iremos usar são todos grátis:
A primeira a coisa a fazer é instalar ao .NET Core SDK 5.0 no seu ambiente.
Após a instalação, para verificar o ambiente abra uma janela do PowerShell e digite o comando: dotnet --version
Com o .NET Core SDK instalado você pode instalar o Visual Studio 2019 Community que é grátis e a seguir instalar o Docker Desktop for Windows que também é grátis e iniciar o desenvolvimento.
Criando a Web API ASP .NET Core
Vamos criar uma solução em branco usando o template Blank Solution com o nome ApiMySqlDocker:
A seguir no menu File selecione Add-> New Project e selecione o template ASP .NET Core Web API e clique em Next;
Informe o nome ApiMySqlDocker e clique em Next;
A seguir selecione o Target Framework, Authentication Type e demais configurações conforme mostrada na figura:
Note que não habilitamos o HTTPS para evitar ter que habilitar um certificado no contêiner.
Agora vamos remover os arquivos WeatherForecastController.cs e WeatherForecast.cs do projeto criado.
A seguir inclua no projeto uma referência ao pacote Pomelo.EntityFrameworkCore.MySql abrindo a janela Package Manager Console e digitando o comando:
install-package Pomelo.EntityFrameworkCore.MySql -Version 5.0.0
Como vamos gerar o Controlador ProductsController a partir do Scaffolding precisamos instalar também o pacote :
install-package Microsoft.EntityFrameworkCore.Design -Version 5.0.6
Crie uma pasta Entities no projeto e a seguir inclua nesta pasta a classe Product que representa a nossa entidade de domínio:
public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } public string Description { get; set; } } |
Crie uma pasta DataContext e inclua nesta pasta a classe ApplicationDbContext :
using EFCoreSqlServer.Entities; using Microsoft.EntityFrameworkCore;
namespace EFCoreSqlServer.DataContext
public DbSet<Product> Products { get; set; } |
Definimos o arquivo de contexto que realiza o mapeamento ORM e permite definir as opções do contexto informando a string de conexão e o provedor do banco de dados.
O método Database.EnsureCreated() garante que o banco de dados para o contexto exista. Se ele existir, nenhuma ação será realizada. Se ele não existir, o banco de dados e todo o seu esquema serão criados.
Configurando o serviço e a string de conexão
Vamos registrar o contexto como um serviço no arquivo Startup e definir o provedor e a string de conexão com o MySQL que iremos usar.
No método ConfigureServices inclua o código a seguir:
public void ConfigureServices(IServiceCollection services) { string mySqlConnectionStr = Configuration.GetConnectionString("DefaultConnection"); services.AddDbContextPool<ApplicationDbContext>(options => options.UseMySql(mySqlConnectionStr, ServerVersion.AutoDetect(mySqlConnectionStr))); services.AddControllers(); |
Agora abra o arquivo appsettings.json e crie a seção ConnectionStrings definindo a string de conexão com o nome do banco de dados, o usuário e a senha para acessar o SQL Server.
{ "ConnectionStrings": { "DefaultConnection": "Server=localhost;DataBase=ProductsDB;Uid=user;Pwd=numsey" }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*" } |
Estou assumindo que o banco de dados e as tabelas já existam, no entanto para criar o banco e as tabelas basta aplicar o Migrations usando o comando
add-migration Inicial
A seguir basta verificar o script gerado e executar o comando para aplicar o script e gerar o banco e as tabelas:
update-database
Criando a API - ProductsController
Como nosso objetivo é mostrar a conteinerização da API e do MySQL eu vou gerar o controlador de forma automática usando a ferramenta Scaffold do Visual Studio.
Para criar o controlador clique com o botão direito do mouse sobre a pasta Controllers e selecione a opção Add -> Controller;
Na janela - Add New Scaffolded Item - selecione API e a seguir a opção - API Controller with actions, using Entity Framework e clique em Add;
Na próxima janela informe :
Clique em Add e aguarde...
Será gerado o arquivo ProductsController contendo os métodos Action para as operações CRUD usando os verbos Http : Get, Post, Put e Delete.
using ApiMySqlDocker.DataContext; using ApiMySqlDocker.Entities; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks;
namespace ApiMySqlDocker.Controllers public ProductsController(ApplicationDbContext context) [HttpGet] [HttpGet("{id}")] if (product == null) return product; [HttpPut("{id}")] _context.Entry(product).State = EntityState.Modified; try return NoContent(); [HttpPost] return CreatedAtAction("GetProduct", new { id = product.Id }, product); [HttpDelete("{id}")] _context.Products.Remove(product); return NoContent(); private bool ProductExists(int id) |
Com isso foram criados os métodos que definem os endpoints da API e realizam um CRUD onde podemos incluir, consultar, excluir e editar produtos.
O código gerado faz a injeção do DbContext representando pela classe ApplicationDbContext e assim não vamos criar um repositório.
Executando o projeto neste momento temos nossa API Products exibindo os endpoints definidos na interface do Swagger.
A seguir criamos os métodos que definem os endpoints da API e realizam um CRUD onde podemos incluir, consultar, excluir e editar produtos.
Temos assim nossa API criada e funcionando acessando o banco de dados MySQL local e agora precisamos criar o contêiner usando a imagem do MySQL a partir do Docker Hub e a seguir criar o contêiner da aplicação API e acessar o contêiner do MySQL.
Na próxima parte do artigo vamos criar o Dockerfile e o arquivo de composição usando o Docker Compose via integração com o Visual Studio 2019.
"Vigiai, estai firmes na fé; portai-vos varonilmente, e
fortalecei-vos.
Todas as vossas coisas sejam feitas com amor."
1 Coríntios 16:13,14
Referências:
C# - Tasks x Threads. Qual a diferença
VB .NET - Datas, horas: conceitos e operações
C# - Programação Assíncrona como : Asycn e Task
O tratamento de datas no VB.NET
C# - Obtendo a data e a hora por TimeZone
Docker - Uma introdução básica -
Docker - Criando um Contâiner para .NET Core ...
Docker - Trabalhando com contêineres
Motivos para usar Docker com .NET Core -
Docker - MiniCurso Básico