연습 - EF Core를 최소 API에 추가
회사의 개발자인 여러분은 새로운 최소 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에 데이터 지속성을 추가합니다.
터미널에서
dotnet new
를 실행하여 웹 API를 만듭니다.dotnet new web -o PizzaStore -f net8.0
PizzaStore 디렉터리가 표시됩니다.
다음 명령을 입력하여 PizzaStore 디렉터리로 이동합니다.
cd PizzaStore
Swashbuckle 패키지를 설치합니다.
dotnet add package Swashbuckle.AspNetCore --version 6.5.0
Visual Studio Code에서 프로젝트를 엽니다.
Visual Studio Code를 사용하여 프로젝트 루트에 Db.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를 사용하여 이 데이터 모델을 데이터베이스 테이블에 매핑합니다.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 추가
항목을 할 일 목록에 저장하려면 EntityFrameworkCore.InMemory
패키지를 설치합니다.
Ctrl + '를 눌러 Visual Studio Code에서 터미널을 엽니다. 터미널 창에서 다음 코드를 입력하여 EF Core InMemory 패키지를 추가합니다.
dotnet add package Microsoft.EntityFrameworkCore.InMemory --version 8.0
Program.cs 및 Pizza.cs 파일의 맨 위에
using Microsoft.EntityFrameworkCore;
를 추가합니다.이제 프로젝트에 EF Core를 추가했으므로 원하는 데이터에 코드를 연결하여 데이터를 저장하고 쿼리할 수 있습니다. 이 단계를 수행하려면
PizzaDb
클래스를 만듭니다.PizzaDb
클래스는 다음 작업을 수행합니다.- 데이터베이스의
Pizza
목록에서Pizzas
속성을 노출합니다. UseInMemoryDatabase
를 사용하여 메모리 내 데이터베이스 스토리지를 연결합니다. 데이터는 앱이 실행되는 동안에는 여기에 저장됩니다.
- 데이터베이스의
메모리 내 데이터베이스를 설정하려면 Pizza.cs 파일 하단에 다음 코드를 추가합니다(마지막
}
위에).PizzaStore.Models
네임스페이스 내에 두 개의 클래스 정의가 있습니다.class PizzaDb : DbContext { public PizzaDb(DbContextOptions options) : base(options) { } public DbSet<Pizza> Pizzas { get; set; } = null!; }
DbContext
는 데이터베이스에서 엔터티 인스턴스를 쿼리하고 저장하는 데 사용되는 연결 또는 세션을 나타냅니다.Program.cs 파일의 상단에
using PizzaStore.Models;
를 추가합니다.Program.cs에서
AddSwaggerGen
호출 앞에 다음 코드를 추가합니다.builder.Services.AddDbContext<PizzaDb>(options => options.UseInMemoryDatabase("items"));
항목 목록 반환
피자 목록의 항목 목록에서 읽으려면
app.Run();
호출 위에 다음 코드를 추가하여 “/pizzas” 경로를 추가합니다.app.MapGet("/pizzas", async (PizzaDb db) => await db.Pizzas.ToListAsync());
애플리케이션 실행
모든 변경 내용을 저장했는지 확인합니다. 터미널에서
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
브라우저에서 https://localhost:{PORT}/swagger으로 이동합니다.
GET /pizzas
단추를 선택한 다음 사용해 보기 및 실행을 선택합니다.Response body
아래에 빈 목록이 표시됩니다.터미널에서 Ctrl+C를 눌러 프로그램 실행을 중지합니다.
새 항목 만들기
Pizzas 목록에 대한 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
가 표시됩니다. 피자 목록에 새 항목을 추가하는 방법:
POST /pizza를 선택합니다.
사용해 보기를 선택합니다.
요청 본문을 다음 JSON으로 바꿉니다.
{ "name": "Pepperoni", "description": "A classic pepperoni pizza" }
실행을 선택합니다.
목록에 있는 항목을 읽는 방법:
GET /pizzas를 선택합니다.
사용해 보기를 선택합니다.
실행을 선택합니다.
Response body
에는 방금 추가된 항목이 포함됩니다.[ { "id": 1, "name": "Pepperoni", "description": "A classic pepperoni pizza" } ]
터미널에서 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 테스트
Swagger UI에서 PUT /pizza/{id}를 선택합니다.
사용해 보기를 선택합니다.
id 텍스트 상자에 1을 입력합니다.
마지막으로
Request body
를 업데이트합니다. 아래 JSON을 붙여넣고name
을Pineapple
로 변경합니다.{ "id": 1, "name": "Pineapple" }
실행을 선택합니다.
코드를 테스트하려면 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 인터페이스를 사용하여 항목을 삭제해 봅니다.
이 단원에서는 EF Core를 기존 최소 API 애플리케이션에 추가하고 메모리 내 데이터베이스를 사용하여 데이터를 저장했습니다. 지금부터는 애플리케이션 종료 사이에 데이터가 지속되도록 실제 데이터베이스를 사용하여 데이터를 저장하는 방법을 알아봅니다.