Exercício – Adicionar o EF Core à API mínima

Concluído

Você é desenvolvedor de uma empresa e você e sua empresa já ouviram falar da nova API mínima. Seu gerente pediu que você criasse um projeto para ele para que você possa discutir se deseja usá-lo em seu próximo projeto.

Observação

Este módulo usa a CLI (interface de linha de comando) do .NET e o Visual Studio Code para desenvolvimento local. Depois de concluir este módulo, você pode aplicar os conceitos usando o Visual Studio (Windows), o Visual Studio para Mac (macOS) ou o desenvolvimento contínuo usando o Visual Studio Code (Windows, Linux, & macOS).

Este módulo usa o SDK do .NET 8.0. Verifique se você tem o .NET 8.0 instalado executando o seguinte comando em seu terminal de comando preferencial:

dotnet --list-sdks

Uma saída semelhante ao seguinte exemplo aparece:

6.0.317 [C:\Program Files\dotnet\sdk]
7.0.401 [C:\Program Files\dotnet\sdk]
8.0.100 [C:\Program Files\dotnet\sdk]

Verifique se uma versão que começa com 8 está listada. Se nenhum estiver listado ou o comando não for encontrado, instale o SDK do .NET 8.0 mais recente.

Configurar o projeto

Primeiro, você precisa criar um projeto. Você instalou o .NET 6 e está pronto para começar. Nesta unidade, você adicionará persistência de dados a uma API de gerenciamento de pizza.

  1. Em um terminal, crie uma API Web executando dotnet new:

    dotnet new web -o PizzaStore -f net8.0
    

    Você deve ver o diretório PizzaStore .

  2. Vá para o diretório PizzaStore inserindo o seguinte comando:

    cd PizzaStore
    
  3. Instale o pacote Swashbuckle:

    dotnet add package Swashbuckle.AspNetCore --version 6.5.0
    
  4. Abra o projeto no Visual Studio Code.

  5. Usando o Visual Studio Code, crie um arquivo Pizza.cs na raiz do projeto e forneça o seguinte conteúdo:

    namespace PizzaStore.Models 
    {
        public class Pizza
        {
              public int Id { get; set; }
              public string? Name { get; set; }
              public string? Description { get; set; }
        }
    }
    

    A classe anterior Pizza é um objeto simples que representa uma pizza. Esse código é seu modelo de dados. Posteriormente, você usará o Entity Framework (EF) Core para mapear esse modelo de dados para uma tabela de banco de dados.

  6. Abra Program.cs e adicione o código realçado:

    using Microsoft.OpenApi.Models;
    
    var builder = WebApplication.CreateBuilder(args);
    
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddSwaggerGen(c =>
    {
         c.SwaggerDoc("v1", new OpenApiInfo {
             Title = "PizzaStore API",
             Description = "Making the Pizzas you love",
             Version = "v1" });
    });
    
    var app = builder.Build();
    if (app.Environment.IsDevelopment())
    {
       app.UseSwagger();
       app.UseSwaggerUI(c =>
       {
          c.SwaggerEndpoint("/swagger/v1/swagger.json", "PizzaStore API V1");
       });
    }
    
    app.MapGet("/", () => "Hello World!");
    
    app.Run();
    

    Você poderá receber um prompt do Visual Studio Code para adicionar ativos para depurar o projeto. Selecione Yes na caixa de diálogo.

Adicionar o EF Core ao projeto

Para armazenar os itens na lista to-do, instale o EntityFrameworkCore.InMemory pacote.

  1. Pressione Ctrl+' para abrir um terminal no Visual Studio Code. No novo terminal, insira o seguinte código para adicionar o pacote InMemory do EF Core:

    dotnet add package Microsoft.EntityFrameworkCore.InMemory --version 8.0
    
  2. Adicione using Microsoft.EntityFrameworkCore; à parte superior dos arquivos Program.cs e Pizza.cs .

    Agora que você tem o EF Core adicionado ao projeto, você pode conectar seu código aos dados que deseja salvar e consultá-lo. Para fazer essa etapa, crie uma PizzaDb classe. A PizzaDb classe realizará as seguintes tarefas:

    • Exponha a sua propriedade Pizzas da sua lista de Pizza no banco de dados.
    • Use UseInMemoryDatabase para conectar o armazenamento de banco de dados na memória. Seus dados são armazenados aqui enquanto o aplicativo estiver em execução.
  3. Para configurar o banco de dados na memória, adicione o seguinte código à parte inferior do arquivo Pizza.cs (acima do final }). Você terá duas definições de classe no PizzaStore.Models namespace.

    class PizzaDb : DbContext
    {
        public PizzaDb(DbContextOptions options) : base(options) { }
        public DbSet<Pizza> Pizzas { get; set; } = null!;
    }
    

    DbContext representa uma conexão ou sessão usada para consultar e salvar instâncias de entidades em um banco de dados.

  4. Adicione using PizzaStore.Models; à parte superior do arquivo Program.cs .

  5. Em Program.cs, antes da chamada a AddSwaggerGen, adicione o seguinte código:

    builder.Services.AddDbContext<PizzaDb>(options => options.UseInMemoryDatabase("items"));
    

Retornar uma lista de itens

  • Para ler de uma lista de itens na lista de pizzas, adicione o seguinte código acima da chamada para app.Run();, para adicionar uma rota "/pizzas":

    app.MapGet("/pizzas", async (PizzaDb db) => await db.Pizzas.ToListAsync());
    

Executar o aplicativo

  1. Verifique se você salvou todas as alterações. Execute o aplicativo chamando dotnet run no terminal. Essa ação criará o aplicativo e o hospedará em uma porta de 5000 a 5300. O HTTPS terá uma porta selecionada para ele no intervalo 7000-7300.

    Observação

    Se você quiser substituir o comportamento de seleção de porta aleatória, poderá definir as portas a serem usadas em launchSettings.json.

    dotnet run
    

    Veja como a saída pode ser no terminal:

    Building...
     info: Microsoft.Hosting.Lifetime[14]
           Now listening on: https://localhost:7200
     info: Microsoft.Hosting.Lifetime[14]
           Now listening on: http://localhost:5100
     info: Microsoft.Hosting.Lifetime[0]
           Application started. Press Ctrl+C to shut down.
     info: Microsoft.Hosting.Lifetime[0]
           Hosting environment: Development
     info: Microsoft.Hosting.Lifetime[0]
           Content root path: /<path>/PizzaStore
    
  2. No navegador, acesse https://localhost:{PORT}/swagger. Selecione o GET /pizzas botão, seguido por Experimentar e Executar. Você verá que a lista está vazia em Response body.

  3. No terminal, pressione Ctrl+C para parar de executar o programa.

Criar itens

Vamos adicionar o código a POST novos itens à lista de pizzas. Em Program.cs, adicione o seguinte código sob o app.MapGet que você criou anteriormente.

app.MapPost("/pizza", async (PizzaDb db, Pizza pizza) =>
{
    await db.Pizzas.AddAsync(pizza);
    await db.SaveChangesAsync();
    return Results.Created($"/pizza/{pizza.Id}", pizza);
});

Testar a API

Verifique se você salvou todas as alterações e execute o aplicativo novamente. Volte para a interface do usuário do Swagger e agora você deve ver POST/pizza. Para adicionar novos itens à lista de pizza:

  1. Selecione POST /pizza.

  2. Selecione Experimentar.

  3. Substitua o corpo da solicitação pelo seguinte JSON:

    {
        "name": "Pepperoni",
        "description": "A classic pepperoni pizza"
    }
    
  4. Selecione Executar.

Para ler os itens na lista:

  1. Selecione GET /pizzas.

  2. Selecione Experimentar.

  3. Selecione Executar.

    Ele Response body incluirá os itens que acabaram de ser adicionados.

    [
      {
        "id": 1,
        "name": "Pepperoni",
        "description": "A classic pepperoni pizza"
      }
    ]
    
  4. Pressione Ctrl+C no terminal para parar de executar o aplicativo. Para o restante deste exercício, interrompa e reinicie o aplicativo conforme desejado para testar suas alterações. Salve todas as alterações antes de você dotnet run!

Obter um único item

Para GET (OBTER) um item por id, adicione o código na rota app.MapPost que você criou anteriormente.

app.MapGet("/pizza/{id}", async (PizzaDb db, int id) => await db.Pizzas.FindAsync(id));

Testar GET por ID

Para testar essa operação, você pode acessar https://localhost:{PORT}/pizza/1 ou usar a interface do usuário do Swagger. Como você está usando um banco de dados na memória, a pizza criada anteriormente não será listada se você reiniciou o aplicativo. Portanto, você precisará usar sua operação POST para adicioná-la novamente.

Atualizar um item

Para atualizar um item existente, adicione o código na GET /pizza/{id} rota que você criou:

app.MapPut("/pizza/{id}", async (PizzaDb db, Pizza updatepizza, int id) =>
{
      var pizza = await db.Pizzas.FindAsync(id);
      if (pizza is null) return Results.NotFound();
      pizza.Name = updatepizza.Name;
      pizza.Description = updatepizza.Description;
      await db.SaveChangesAsync();
      return Results.NoContent();
});

Testar PUT

  1. Selecione PUT /pizza/{id} na interface do usuário do Swagger.

  2. Selecione Experimentar.

  3. Na caixa de texto ID, insira 1.

  4. Por fim, atualize Request body. Cole o JSON a seguir e altere name para Pineapple.

    {
       "id": 1,
       "name": "Pineapple"
    }
    
  5. Selecione Executar.

Para testar o código, role de volta para GET /pizza/{id}. A pizza agora tem o nome Pineapple.

Excluir um item

Para excluir um item existente, adicione o código sob PUT /pizza/{id} o qual você criou anteriormente:

app.MapDelete("/pizza/{id}", async (PizzaDb db, int id) =>
{
   var pizza = await db.Pizzas.FindAsync(id);
   if (pizza is null)
   {
      return Results.NotFound();
   }
   db.Pizzas.Remove(pizza);
   await db.SaveChangesAsync();
   return Results.Ok();
});

Testar DELETE

Agora tente excluir um item usando a interface swagger.

Nesta unidade, você adicionou o EF Core a um aplicativo de API mínimo existente e usou um banco de dados na memória para armazenar os dados. Em seguida, você aprenderá a usar um banco de dados real para armazenar os dados para que ele persista entre desligamentos de aplicativos.