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

Concluído

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

Observação

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

Este módulo usa o SDK do .NET 8.0. Certifique-se de ter o .NET 8.0 instalado executando o seguinte comando no seu terminal de comando preferido:

dotnet --list-sdks

Poderá ver um resultado semelhante ao exemplo seguinte:

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

Certifique-se de que 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 da 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 digitando 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 de Pizza.cs na raiz do projeto e forneça a ele 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 Pizza anterior é um objeto simples que representa uma pizza. Este código é o seu modelo de dados. Mais tarde, 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ê pode receber um prompt do Visual Studio Code para adicionar recursos para ajudar a depurar o projeto. Selecione Yes na caixa de diálogo.

Adicionar EF Core ao projeto

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

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

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

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

    • Exponha a sua propriedade Pizzas da sua lista de Pizza na base 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 seu banco de dados na memória, adicione o seguinte código na parte inferior do arquivo Pizza.cs (acima do arquivo final }). Você terá duas definições de classe dentro do namespace PizzaStore.Models.

    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 seu ficheiro Program.cs .

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

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

Retornar uma lista de itens

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

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

Execute o aplicativo

  1. Certifique-se de que guardou todas as alterações. Execute o aplicativo chamando dotnet run no terminal. Esta ação irá criar o aplicativo e hospedá-lo em uma porta de 5000-5300. HTTPS terá uma porta selecionada para ele no intervalo 7000-7300.

    Observação

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

    dotnet run
    

    Veja como a saída pode parecer 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 seu browser, aceda a https://localhost:{PORT}/swagger. Selecione o GET /pizzas botão, seguido de 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 novos itens

Vamos adicionar o código para POST novos itens à lista de pizzas. No 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

Certifique-se de que guardou todas as alterações e execute a aplicação novamente. Volte para a interface do usuário do Swagger e agora você deve ver POST/pizza. Para adicionar novos itens à lista de pizzas:

  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 da lista:

  1. Selecione GET /pizzas.

  2. Selecione Experimentar.

  3. Selecione Executar.

    O Response body incluirá os itens que acabamos de adicionar.

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

Obter um único item

Para OBTER um item por id, adicione o código na rota app.MapPost que criaste anteriormente.

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

Teste do GET por ID

Para testar essa operação, você pode ir para 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 que você criou anteriormente não será listada se você tiver reiniciado o aplicativo. Então, você precisará usar sua operação POST para adicioná-lo novamente.

Atualizar um item

Para atualizar um item existente, adicione o código sob a rota GET /pizza/{id} 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();
});

Teste PUT

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

  2. Selecione Experimentar.

  3. Na caixa de texto com ID, digite 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, volte para GET /pizza/{id}. A pizza agora tem o nome Pineapple.

Excluir um item

Para excluir um item existente, adicione o código em PUT /pizza/{id} que 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();
});

Testando 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á como usar um banco de dados real para armazenar os dados para que eles persistam entre os desligamentos do aplicativo.