ASP .NET Core  - Consumindo uma Web API com React - I


  Neste artigo vamos mostrar como crir e consumir uma Web API ASP .NET Core usando uma aplicação React.

A ASP .NET Core é um recurso para backend muito poderoso sendo um dos frameworks com melhor desempenho neste quesito. Combine isso com o poder do React e outras ferramentas como SignalR, Entity Framework, Redux e TypeScript e você será capaz de criar sites incríveis com funcionalidades poderosas que seus clientes irão adorar.

Assim neste artigo iremos criar uma API usando a ASP .NET Core 5 e depois vamos consumir esta API usando uma aplicação React.

A figura abaixo dá uma visão geral do que iremos criar e das tecnologias que iremos usar para atingir o nosso objetivo:

Assim iremos criar o projeto Web API com ASP .NET Core 5 usando:

  1. NET 5.0
  2. ASP .NET Core 5.0
  3. EF Core 5.0
  4. SQL Server
  5. VS 2019 Community
  6. JWT

Após criar a API vamos criar uma aplicação React para consumir a API usando os seguinte recursos:

  1. React (17.02)
  2. VS Code
  3. Node.js
  4. npm
  5. Axios

Vamos iniciar criando o projeto Web API usando o VS 2019 Community para gerenciar informações de alunos.

Criando a Web API no VS 2019

Abra o VS 2019 e clique em New Project e selecione o template ASP .NET Core Web API e clique em Next;

Informe o nome AlunosApi e clique em Next;

A seguir selecione o Target Framework, Authentication Type e demais configurações conforme mostrada na figura:

Clique em Create.

A seguir remova o controlador criado por padrão na pasta Controllers e a classe WeatherForecast.cs do projeto.

Para iniciar vamos incluir no projeto os seguinte  pacotes:

Vamos criar agora as seguintes pastas no projeto :

  1. Context
  2. Models
  3. Services

Na pasta Models vamos criar a entidade Aluno que representa o nosso modelo de domínio:

using System.ComponentModel.DataAnnotations;
namespace AlunosApi.Models
{
    public partial class Aluno
    {
        [Key]
        public int Id { get; set; }        
        [Required]
        [StringLength(80)]
        public string Nome { get; set; }
        [Required]
        [EmailAddress]
        [StringLength(100)]
        public string Email { get; set; }
        [Required]
        public int Idade { get; set; }
    }
}

Criamos 4 propriedades onde aplicamos os atributos Data Annotations de forma a definir os campos como obrigatórios e também definir o tamanho do nome e email. Com isso o EF Core irá criar as colunas na tabela como NOT NULL e vai definir um tamanho para as colunas usando NVARCHAR.

Na pasta Context vamos criar a classe AppDbContext que representa uma sessão com o banco de dados que iremos usar e deriva da classe DbContext. Uma instância da classe de contexto representa os padrões de unidade de trabalho e repositório em que pode combinar várias alterações em uma única transação de banco de dados.

A classe de contexto é usada para consultar ou salvar dados no banco de dados e também é usada para configurar classes de domínio, mapeamentos relacionados ao banco de dados, configurações de controle de alterações, armazenamento em cache, transações, etc.

using AlunosApi.Models;
using AlunosApi.Services;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;

namespace AlunosApi.Context
{
    public class AppDbContext : DBContext
    {
        public AppDbContext(DbContextOptions<AppDbContext> options)
          : base(options)
        {
        }
        public virtual DbSet<Aluno> Alunos { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {

            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<Aluno>().HasData(
                new Aluno
                {
                    Id = 1,
                    Nome = "Maria da Penha",
                    Email = "mariapenha@yahoo.com",
                    Idade = 23
                },
                new Aluno
                {
                    Id = 1,
                    Nome = "Manuel Bueno",
                    Email = "manuelbueno@yahoo.com",
                    Idade = 22
                }
            );
        }
    }
}

Na classe de contexto estamos mapeando a entidade Aluno para a tabela Alunos que será criada no SQL Server e também estamos usando a propriedade HasData no método OnModelCreating() para popular a tabela Alunos com dados iniciais.

Precisamos agora registrar este contexto como um serviço para poder usar a sua instância e acessar os dados através de consultas LINQ.

Para isso no arquivo Startup no método ConfigureServices vamos incluir  o código abaixo:

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

            services.AddDbContext<AppDbContext>(options =>
                options.
UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

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

            });
        }

Percebemos neste método o serviço do Swagger que foi configurado na criação do projeto e incluímos o código onde definimos as opções do contexto como o provedor do banco de dados SQL Server (UseSqlServer) e a string de conexão com o nome de DefaultConnection.

Precisamos agora definir a string de conexão no arquivo appsettings.json :

{
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=.sqlexpress;Initial Catalog=
AlunosDemoDB;Integrated Security=True;"
  },

  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

Criamos a seção ConnectionStrings e atribuímos a string de conexão para DefaultConnection onde usamos a instância local do SQL Server e definimos o nome do banco de dados a ser criado como AlunosDemoDB.

Nota: Aqui você deve usar a SUA string de conexão e não copiar a que esta definida pois ela funciona apenas no meu ambiente.

Agora já temos toda a configuração pronta para poder gerar o banco de dados e a tabela no SQL Server, e,  vamos fazer isso usando o recurso Migrations do EF Core.

Aplicando o Migrations e gerando o banco e a tabela

O recurso Migrations é uma forma de manter o esquema do banco de dados em sincronia com o modelo de entidades do EF Core, preservando os dados.

As migrações do EF Core são um conjunto de comandos que você pode executar no Console do gerenciador de pacotes NuGet ou na interface de linha de comando dotnet (CLI). 

Os comandos principais são:

  1. add-migration  - Cria um script de migração para aplicação os comandos no banco de dados;
  2. remove-migration - Remove a última migração criada;
  3. update-database - Aplica o script de migração criado executando os seus comandos;

Assim vamos dar um Build na solução e verificar se não existem erros (se houver basta usar o remove-migration e refazer) e a seguir vamos abrir a janela do Console do gerenciador de pacotes NuGet e digitar o comando:  add-migration inicial

Ao final este comando vai criar no projeto a pasta Migrations contendo os arquivos:

  1. <timestamp>_<Nome_Migração>.cs: O arquivo de migração principal que inclui operações de migração nos métodos Up() e Down(). O método Up() inclui o código para criar objetos de banco de dados e o método Down() inclui o código para remover objetos de banco de dados.
  2. <timestamp>_<Nome_Migração>.Designer.cs: O arquivo de metadados de migração que contém informações usadas pelo EF Core.
  3. <contextclassname>ModelSnapshot.cs: Um instantâneo do seu modelo atual. Isso é usado para determinar o que mudou ao criar a próxima migração.

Após verificar o arquivo de script gerado, e,  estando tudo corretamente definido podemos aplicar a migração emitindo o comando: update-database

Isso irá criar no SQL Server o banco AlunosDemoDB e a tabela Alunos contendo dois registros conforme mostramos abaixo:

Temos assim o banco e a tabela criados e podemos continuar.

Na próxima parte do artigo iremos criar o serviço e o controlador para gerenciar alunos.

"E eu, quando o vi, caí a seus pés como morto; e ele pôs sobre mim a sua destra, dizendo-me: Não temas; Eu sou o primeiro e o último; E o que vivo e fui morto, mas eis aqui estou vivo para todo o sempre. Amém. E tenho as chaves da morte e do inferno."
Apocalipse 1:17,18

Referências:


José Carlos Macoratti