연습 - EF Core를 최소 API에 추가

완료됨

여러분은 회사의 개발자이고, 여러분과 여러분의 회사는 새로운 최소 API에 대해 들었습니다. 관리자가 다음 프로젝트에서 사용할지 여부를 논의할 수 있도록 프로젝트를 만들어 달라고 요청했습니다.

비고

이 모듈에서는 로컬 개발에 .NET CLI(명령줄 인터페이스) 및 Visual Studio Code를 사용합니다. 이 모듈을 완료하면 Visual Studio(Windows), Mac용 Visual Studio(macOS) 또는 Visual Studio Code(Windows, Linux 및 macOS)를 사용한 연속 개발을 사용하여 개념을 적용할 수 있습니다.

이 모듈에서는 .NET 8.0 SDK를 사용합니다. 기본 설정 터미널에서 다음 명령을 실행하여 .NET 8.0이 설치되어 있는지 확인합니다.

dotnet --list-sdks

다음 예제와 유사한 출력이 표시됩니다.

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

8으로 시작하는 버전이 나열되어 있는지 확인합니다. 나열되지 않았거나 명령을 찾을 수 없는 경우 최신 .NET 8.0 SDK를 설치합니다.

프로젝트 설정

먼저 프로젝트를 만들어야 합니다. .NET 6을 설치했으며 사용할 준비가 완료되었습니다. 이 단원에서는 피자 관리 API에 데이터 지속성을 추가합니다.

  1. 터미널에서 다음을 실행하여 웹 API를 만듭니다 dotnet new.

    dotnet new web -o PizzaStore -f net8.0
    

    PizzaStore 디렉터리가 표시됩니다.

  2. 다음 명령을 입력하여 PizzaStore 디렉터리로 이동합니다.

    cd PizzaStore
    
  3. Swashbuckle 패키지를 설치합니다.

    dotnet add package Swashbuckle.AspNetCore --version 6.5.0
    
  4. Visual Studio Code에서 프로젝트를 엽니다.

  5. Visual Studio Code를 사용하여 프로젝트 루트에 Pizza.cs 파일을 만들고 다음 콘텐츠를 제공합니다.

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

    앞의 Pizza 클래스는 피자를 나타내는 간단한 개체입니다. 이 코드는 데이터 모델입니다. 나중에 EF(Entity Framework) Core를 사용하여 이 데이터 모델을 데이터베이스 테이블에 매핑합니다.

  6. Program.cs 열고 강조 표시된 코드를 추가합니다.

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

    Visual Studio Code에서 프로젝트를 디버그하기 위해 자산을 추가하라는 프롬프트가 표시될 수 있습니다. 대화 상자에서 Yes을 선택합니다.

프로젝트에 EF Core 추가

to-do 목록에 항목을 저장하려면 패키지를 설치합니다 EntityFrameworkCore.InMemory .

  1. Ctrl+'를 눌러 Visual Studio Code에서 터미널을 엽니다. 새 터미널에서 다음 코드를 입력하여 EF Core InMemory 패키지를 추가합니다.

    dotnet add package Microsoft.EntityFrameworkCore.InMemory --version 8.0
    
  2. using Microsoft.EntityFrameworkCore;Pizza.cs 파일의 맨 위에 추가 합니다.

    이제 EF Core를 프로젝트에 추가했으므로 저장하려는 데이터에 코드를 연결하고 쿼리할 수 있습니다. 이 단계를 수행하려면 클래스를 만듭니다 PizzaDb . 클래스는 PizzaDb 다음 작업을 수행합니다.

    • 당신의 Pizzas 목록에서 Pizza 속성을 데이터베이스에 노출하십시오.
    • 메모리 내 데이터베이스 스토리지를 연결하는 데 사용합니다 UseInMemoryDatabase . 앱이 실행되는 한 데이터는 여기에 저장됩니다.
  3. 메모리 내 데이터베이스를 설정하려면 Pizza.cs 파일의 맨 아래에 다음 코드를 추가합니다(마지막 }위). PizzaStore.Models 네임스페이스 안에 두 개의 클래스 정의가 있습니다.

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

    DbContext 는 데이터베이스에 엔터티 인스턴스를 쿼리하고 저장하는 데 사용되는 연결 또는 세션을 나타냅니다.

  4. using PizzaStore.Models; 파일의 맨 위에 를 추가합니다.

  5. Program.cs 호출AddSwaggerGen하기 전에 다음 코드를 추가합니다.

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

항목 목록 반환

  • 피자 목록의 항목 목록에서 읽으려면 호출 app.Run(); 위에 다음 코드를 추가하여 "/pizzas" 경로를 추가합니다.

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

애플리케이션 실행

  1. 모든 변경 내용을 저장했는지 확인합니다. 터미널에서 호출 dotnet run 하여 앱을 실행합니다. 이 작업은 앱을 빌드하고 5000-5300의 포트에서 호스트합니다. HTTPS에는 7000-7300 범위의 포트가 선택됩니다.

    비고

    임의 포트 선택 동작을 재정의하려면 launchSettings.json사용할 포트를 설정할 수 있습니다.

    dotnet run
    

    터미널에서 출력의 모양은 다음과 같습니다.

    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. 브라우저에서 https://localhost:{PORT}/swagger으로 이동합니다. GET /pizzas 단추를 선택한 다음, 사용해 보기실행합니다. 아래에 목록이 비어 있는 것을 볼 수 있습니다 Response body.

  3. 터미널에서 Ctrl+C 를 눌러 프로그램 실행을 중지합니다.

새 항목 만들기

피자 목록에 새 항목에 POST 코드를 추가해 보겠습니다. Program.cs 앞에서 만든 코드 아래에 app.MapGet 다음 코드를 추가합니다.

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

API 테스트

모든 변경 내용을 저장했는지 확인하고 앱을 다시 실행합니다. Swagger UI로 돌아가면 이제 표시됩니다 POST/pizza. 피자 목록에 새 항목을 추가하려면 다음을 수행합니다.

  1. POST /pizza를 선택합니다.

  2. 사용해 보세요를 선택합니다.

  3. 요청 본문을 다음 JSON으로 바꿉다.

    {
        "name": "Pepperoni",
        "description": "A classic pepperoni pizza"
    }
    
  4. 실행을 선택합니다.

목록에서 항목을 읽으려면 다음을 수행합니다.

  1. GET /pizzas를 선택합니다.

  2. 사용해 보세요를 선택합니다.

  3. 실행을 선택합니다.

    Response body 방금 추가된 항목이 포함됩니다.

    [
      {
        "id": 1,
        "name": "Pepperoni",
        "description": "A classic pepperoni pizza"
      }
    ]
    
  4. 터미널에서 Ctrl+C 를 눌러 앱 실행을 중지합니다. 이 연습의 나머지 부분에 대해 변경 내용을 테스트하기 위해 원하는 대로 앱을 중지하고 다시 시작합니다. 모든 변경 내용을 dotnet run하기 전에 반드시 저장하세요!

단일 항목 가져오기

id를 기준으로 항목을 가져오려면 이전에 만든 app.MapPost 경로 아래에 코드를 추가합니다.

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

ID별 GET 테스트

이 작업을 테스트하려면 https://localhost:{PORT}/pizza/1으로 이동하거나 Swagger UI를 사용할 수 있습니다. 메모리 내 데이터베이스를 사용하므로 애플리케이션을 다시 시작한 경우 이전에 만든 피자가 나열되지 않습니다. 따라서 POST 작업을 사용하여 다시 추가해야 합니다.

항목 업데이트

기존 항목을 업데이트하려면 만든 경로 아래에 GET /pizza/{id} 코드를 추가합니다.

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

PUT 테스트

  1. Swagger UI에서 PUT /pizza/{id} 를 선택합니다.

  2. 사용해 보세요를 선택합니다.

  3. ID 텍스트 상자에 1을 입력합니다.

  4. 마지막으로 Request body를 업데이트합니다. 다음 JSON을 붙여넣고 namePineapple로 변경하세요.

    {
       "id": 1,
       "name": "Pineapple"
    }
    
  5. 실행을 선택합니다.

코드를 테스트하려면 뒤로 스크롤합니다 GET /pizza/{id}. 이제 피자의 이름이 Pineapple지정됩니다.

항목 삭제

기존 항목을 삭제하려면 앞에서 만든 코드 아래에 PUT /pizza/{id} 코드를 추가합니다.

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

DELETE 테스트

이제 Swagger 인터페이스를 사용하여 항목을 삭제해 봅니다.

이 단원에서는 기존 최소 API 애플리케이션에 EF Core를 추가하고 메모리 내 데이터베이스를 사용하여 데이터를 저장했습니다. 다음으로, 애플리케이션 종료 간에 유지되도록 실제 데이터베이스를 사용하여 데이터를 저장하는 방법을 알아봅니다.