Exercice : Ajouter EF Core à l’API minimale

Effectué

Vous êtes développeur pour une entreprise, et vous et votre entreprise avez entendu parler de la nouvelle API minimale. Votre responsable vous a demandé de créer un projet pour lui afin de pouvoir discuter s’il faut l’utiliser sur votre prochain projet.

Remarque

Ce module utilise l’interface CLI .NET et Visual Studio Code pour le développement local. À l’issue de ce module, vous pourrez appliquer les concepts avec Visual Studio (Windows) ou Visual Studio pour Mac (macOS), ou poursuivre le développement avec Visual Studio Code (Windows, Linux et macOS).

Ce module utilise le kit de développement logiciel (SDK) .NET 8.0. Assurez-vous que .NET 8.0 est installé en exécutant la commande suivante dans votre terminal de commandes préféré :

dotnet --list-sdks

Une sortie semblable à l’exemple suivant s’affiche :

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

Vérifiez que la liste comporte une version commençant par 8. Si aucune liste n’est répertoriée ou si la commande n’est pas trouvée, installez le kit SDK .NET 8.0 le plus récent.

Configuration du projet

Tout d’abord, vous devez créer un projet. Vous avez installé .NET 6 et vous êtes prêt à démarrer. Dans cette unité, vous allez ajouter la persistance des données à une API de gestion des pizzas.

  1. Dans un terminal, créez une API web en exécutant dotnet new:

    dotnet new web -o PizzaStore -f net8.0
    

    Vous devriez voir le répertoire PizzaStore .

  2. Accédez au répertoire PizzaStore en entrant la commande suivante :

    cd PizzaStore
    
  3. Installez le package Swashbuckle :

    dotnet add package Swashbuckle.AspNetCore --version 6.5.0
    
  4. Ouvrez le projet dans Visual Studio Code.

  5. À l’aide de Visual Studio Code, créez un fichier Pizza.cs à la racine du projet et donnez-lui le contenu suivant :

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

    La classe précédente Pizza est un objet simple qui représente une pizza. Ce code est votre modèle de données. Plus tard, vous allez utiliser Entity Framework (EF) Core pour mapper ce modèle de données à une table de base de données.

  6. Ouvrez Program.cs et ajoutez le code mis en surbrillance :

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

    Vous pouvez recevoir une invite de Visual Studio Code pour ajouter des ressources afin de déboguer le projet. Sélectionnez-le Yes dans la boîte de dialogue.

Ajouter EF Core au projet

Pour stocker les éléments dans la liste to-do, installez le EntityFrameworkCore.InMemory package.

  1. Appuyez sur Ctrl+' pour ouvrir un terminal dans Visual Studio Code. Dans le nouveau terminal, entrez le code suivant pour ajouter le package EF Core InMemory :

    dotnet add package Microsoft.EntityFrameworkCore.InMemory --version 8.0
    
  2. Ajoutez-y using Microsoft.EntityFrameworkCore; en haut de vos fichiers Program.cs et Pizza.cs .

    Maintenant que EF Core est ajouté au projet, vous pouvez lier votre code aux données que vous souhaitez enregistrer et interroger. Pour effectuer cette étape, vous créez une PizzaDb classe. La PizzaDb classe effectue les tâches suivantes :

    • Exposez votre propriété Pizzas à partir de votre liste de Pizza dans la base de données.
    • Utilisez UseInMemoryDatabase pour associer le stockage de base de données en mémoire. Vos données sont stockées ici tant que l’application est en cours d’exécution.
  3. Pour configurer votre base de données en mémoire, ajoutez le code suivant au bas du fichier Pizza.cs (au-dessus de la finale }). Vous aurez deux définitions de classe dans le namespace PizzaStore.Models.

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

    DbContext représente une connexion ou une session utilisée pour interroger et enregistrer des instances d’entités dans une base de données.

  4. Ajoutez-y using PizzaStore.Models; en haut de votre fichier Program.cs .

  5. Dans Program.cs, avant l’appel à AddSwaggerGen, ajoutez le code suivant :

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

Retourner une liste d’éléments

  • Pour lire dans une liste d’éléments de la liste de pizzas, ajoutez le code suivant au-dessus de l’appel à app.Run(); pour ajouter un itinéraire « /pizzas » :

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

Exécuter l’application

  1. Vérifiez que vous avez enregistré tous vos changements. Exécutez l’application en appelant dotnet run dans le terminal. Cette action génère l’application et l’héberge sur un port de 5000 à 5300. HTTPS aura un port sélectionné pour celui-ci dans la plage 7000-7300.

    Remarque

    Si vous souhaitez remplacer le comportement de sélection de port aléatoire, vous pouvez définir les ports à utiliser dans launchSettings.json.

    dotnet run
    

    Voici à quoi ressemble la sortie dans le 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. Dans votre navigateur, accédez à https://localhost:{PORT}/swagger. Sélectionnez le GET /pizzas bouton, puis essayez-le et exécutez. Vous verrez que la liste est vide sous Response body.

  3. Dans le terminal, appuyez sur Ctrl+C pour arrêter l’exécution du programme.

Créer des éléments

Ajoutons le code aux nouveaux éléments POST de la liste des pizzas. Dans Program.cs, ajoutez le code suivant sous celui app.MapGet que vous avez créé précédemment.

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

Tester l’API

Vérifiez que vous avez enregistré toutes vos modifications et réexécutez l’application. Revenez à l’interface utilisateur Swagger et vous devriez maintenant voir POST/pizza. Pour ajouter de nouveaux éléments à la liste de pizzas :

  1. Sélectionnez POST /pizza.

  2. Sélectionnez Essayer.

  3. Remplacez le corps de la requête par le code JSON suivant :

    {
        "name": "Pepperoni",
        "description": "A classic pepperoni pizza"
    }
    
  4. Sélectionnez Exécuter.

Pour lire les éléments de la liste :

  1. Sélectionnez GET /pizzas.

  2. Sélectionnez Essayer.

  3. Sélectionnez Exécuter.

    Les Response body incluront les éléments qui viennent d'être ajoutés.

    [
      {
        "id": 1,
        "name": "Pepperoni",
        "description": "A classic pepperoni pizza"
      }
    ]
    
  4. Appuyez sur Ctrl+C dans le terminal pour arrêter l’exécution de l’application. Pour le reste de cet exercice, arrêtez et redémarrez l’application comme vous le souhaitez pour tester vos modifications. Veillez à enregistrer toutes vos modifications avant de dotnet run!

Obtenir un seul élément

Pour OBTENIR un élément par id, ajoutez le code sous l’itinéraire app.MapPost que vous avez créé précédemment.

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

Tester GET par ID

Pour tester cette opération, vous pouvez soit accéder à https://localhost:{PORT}/pizza/1, soit utiliser l'interface utilisateur Swagger. Comme vous utilisez une base de données en mémoire, la pizza que vous avez créée précédemment ne sera pas répertoriée si vous avez redémarré l’application. Par conséquent, vous devez utiliser votre opération POST pour l’ajouter à nouveau.

Mettre à jour un élément

Pour mettre à jour un élément existant, ajoutez le code sous l’itinéraire GET /pizza/{id} que vous avez créé :

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

Tester PUT

  1. Sélectionnez PUT /pizza/{id} dans l’interface utilisateur Swagger.

  2. Sélectionnez Essayer.

  3. Dans la zone de texte ID , entrez 1.

  4. Enfin, mettez à jour Request body. Collez le code JSON suivant et passez name à Pineapple.

    {
       "id": 1,
       "name": "Pineapple"
    }
    
  5. Sélectionnez Exécuter.

Pour tester le code, faites défiler pour revenir à GET /pizza/{id}. La pizza a maintenant le nom Pineapple.

Supprimer un élément

Pour supprimer un élément existant, ajoutez le code sous PUT /pizza/{id} lequel vous avez créé précédemment :

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

Tests de DELETE

Essayez maintenant de supprimer un élément à l’aide de l’interface Swagger.

Dans cette unité, vous avez ajouté EF Core à une application API minimale existante et utilisé une base de données en mémoire pour stocker les données. Ensuite, vous allez apprendre à utiliser une base de données réelle pour stocker les données afin qu’elles persistent entre les arrêts de l’application.