Ejercicio: Adición de EF Core a la API mínima

Completado

Es desarrollador de una empresa y usted y su empresa han oído hablar de la nueva API mínima. El administrador le ha pedido que cree un proyecto para ello para que pueda analizar si se va a usar en el siguiente proyecto.

Nota:

En este módulo se usan la CLI (interfaz de la línea de comandos) de .NET y Visual Studio Code para el desarrollo local. Cuando complete este módulo, podrá aplicar los conceptos mediante Visual Studio (Windows), Visual Studio para Mac (macOS), o seguir con el desarrollo mediante Visual Studio Code (Windows, Linux y macOS).

En este módulo se usa el SDK de .NET 8.0. Asegúrese de que tiene instalado .NET 8.0 mediante la ejecución del siguiente comando en el terminal de comandos que prefiera:

dotnet --list-sdks

Aparecerá un resultado similar al del ejemplo siguiente:

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

Asegúrese de que aparezca una versión que comience en 8. Si no aparece ninguna o no se encuentra el comando, instale el SDK más reciente de .NET 8.0.

Configuración del proyecto

En primer lugar, debe crear un proyecto. Has instalado .NET 6 y estás listo para empezar. En esta unidad, vas a agregar persistencia de datos a una API de gestión de pizzas.

  1. En un terminal, cree una API web mediante la ejecución dotnet newde :

    dotnet new web -o PizzaStore -f net8.0
    

    Debería ver el directorio PizzaStore .

  2. Para ir al directorio PizzaStore , escriba el siguiente comando:

    cd PizzaStore
    
  3. Instale el paquete Swashbuckle:

    dotnet add package Swashbuckle.AspNetCore --version 6.5.0
    
  4. Abra el proyecto en Visual Studio Code.

  5. Con Visual Studio Code, cree un archivo Pizza.cs en la raíz del proyecto y asígnele el siguiente contenido:

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

    La clase anterior Pizza es un objeto simple que representa una pizza. Este código es el modelo de datos. Más adelante, usará Entity Framework (EF) Core para asignar este modelo de datos a una tabla de base de datos.

  6. Abra Program.cs y agregue el código resaltado:

    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();
    

    Es posible que reciba un mensaje de Visual Studio Code para agregar recursos para depurar el proyecto. Seleccione Yes en el cuadro de diálogo.

Adición de EF Core al proyecto

Para almacenar los elementos en la lista de to-do, instale el EntityFrameworkCore.InMemory paquete.

  1. Presione Ctrl+' para abrir un terminal en Visual Studio Code. En el nuevo terminal, escriba el código siguiente para agregar el paquete InMemory de EF Core:

    dotnet add package Microsoft.EntityFrameworkCore.InMemory --version 8.0
    
  2. Agregue using Microsoft.EntityFrameworkCore; a la parte superior de los archivos Program.cs y Pizza.cs .

    Ahora que ha agregado EF Core al proyecto, puede conectar el código a los datos que desea guardar y consultar. Para realizar este paso, cree una PizzaDb clase. La PizzaDb clase realizará las siguientes tareas:

    • Exponer la propiedad Pizzas de la lista de Pizza en la base de datos.
    • Use UseInMemoryDatabase para conectar el almacenamiento de la base de datos en memoria. Los datos se almacenan aquí siempre que se ejecute la aplicación.
  3. Para configurar la base de datos en memoria, agregue el código siguiente a la parte inferior del archivo Pizza.cs (encima del final }). Tendrás dos definiciones de clases dentro del PizzaStore.Models espacio de nombres.

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

    DbContext representa una conexión o sesión que se usa para consultar y guardar instancias de entidades en una base de datos.

  4. Agregue using PizzaStore.Models; a la parte superior del archivo Program.cs .

  5. En Program.cs, antes de la llamada a AddSwaggerGen, agregue el código siguiente:

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

Devolver una lista de ítems

  • Para leer una lista de elementos de la lista de pizzas, agregue el código siguiente encima de la llamada a app.Run(); para agregar una ruta "/pizzas":

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

Ejecutar la aplicación

  1. Asegúrese de que ha guardado todos los cambios. Ejecute la aplicación llamando dotnet run a en el terminal. Esta acción compilará la aplicación y la hospedará en un puerto de 5000 a 5300. HTTPS tendrá un puerto seleccionado para él en el intervalo 7000-7300.

    Nota:

    Si desea invalidar el comportamiento de selección de puerto aleatorio, puede establecer los puertos que se usarán en launchSettings.json.

    dotnet run
    

    Este es el aspecto que puede tener la salida en el 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. En el explorador, vaya a https://localhost:{PORT}/swagger. Seleccione el GET /pizzas botón, seguido de Pruébelo y Ejecutar. Verá que la lista está vacía en Response body.

  3. En el terminal, presione Ctrl+C para dejar de ejecutar el programa.

Creación de nuevos elementos

Vamos a agregar el código a nuevos elementos de POST a la lista de pizzas. En Program.cs, agregue el código siguiente en el app.MapGet que creó anteriormente.

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

Prueba de la API

Asegúrese de que ha guardado todos los cambios y vuelva a ejecutar la aplicación. Vuelva a la interfaz de usuario de Swagger y ahora debería ver POST/pizza. Para agregar nuevos elementos a la lista de pizzas:

  1. Seleccione POST /pizza.

  2. Haga clic en Probar.

  3. Reemplace el cuerpo de la solicitud por el siguiente json:

    {
        "name": "Pepperoni",
        "description": "A classic pepperoni pizza"
    }
    
  4. Seleccione Execute(Ejecutar).

Para leer los elementos de la lista:

  1. Seleccione GET /pizzas.

  2. Haga clic en Probar.

  3. Seleccione Execute(Ejecutar).

    Response body Incluirá los elementos que acaba de agregar.

    [
      {
        "id": 1,
        "name": "Pepperoni",
        "description": "A classic pepperoni pizza"
      }
    ]
    
  4. Presione Ctrl+C en el terminal para dejar de ejecutar la aplicación. Para el resto de este ejercicio, detenga y reinicie la aplicación según sea necesario para probar los cambios. Asegúrese de guardar todos los cambios antes de dotnet run.

Obtención de un elemento único

Para obtener un elemento mediante id, agregue el código en la ruta app.MapPost que creó anteriormente.

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

Prueba de GET por identificador

Para probar esta operación, puede ir a https://localhost:{PORT}/pizza/1 o usar la interfaz de usuario de Swagger. Puesto que usa una base de datos en memoria, la pizza que creó anteriormente no aparecerá si ha reiniciado la aplicación. Por lo tanto, deberá usar la operación POST para agregarla de nuevo.

Actualización de un elemento

Para actualizar un elemento existente, agregue el código en la GET /pizza/{id} ruta que creó:

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();
});

Prueba de PUT

  1. Seleccione PUT /pizza/{id} en la interfaz de usuario de Swagger.

  2. Haga clic en Probar.

  3. En el cuadro de texto id , escriba 1.

  4. Por último, actualice Request body. Pegue el siguiente código JSON y cambie name a Pineapple.

    {
       "id": 1,
       "name": "Pineapple"
    }
    
  5. Seleccione Execute(Ejecutar).

Para probar el código, desplácese hacia atrás a GET /pizza/{id}. La pizza ahora tiene el nombre Pineapple.

Eliminación de un elemento

Para eliminar un elemento existente, agregue el código bajo PUT /pizza/{id} que creó 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();
});

Prueba de DELETE

Ahora intente eliminar un elemento mediante la interfaz de Swagger.

En esta unidad, agregó EF Core a una aplicación de API mínima existente y usó una base de datos en memoria para almacenar los datos. A continuación, aprenderá a usar una base de datos real para almacenar los datos para que persista entre los apagados de la aplicación.