0Pricing
C# Academy · 강의

경로 그룹, 매개 변수와 유효성 검사

MapGroup으로 엔드포인트를 구성하고 경로, 쿼리, 본문 매개 변수를 바인딩하며 데이터 주석으로 유효성을 검사합니다.

경로 그룹, 매개 변수와 유효성 검사은(는) CoddyKit의 무료 C# Academy 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 C# Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. C# Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

구성을 위한 라우트 그룹

MapGroup() (.NET 7에서 도입)을 사용하면 관련 엔드포인트를 공통 접두사 아래에 그룹화하고, 각 엔드포인트에 반복해서 적용하지 않고도 미들웨어, 인증 정책, 태그와 같은 공통 구성을 적용할 수 있습니다.

라우트 그룹 만들기

app.MapGroup("/api/products")를 호출한 다음 반환된 그룹에 엔드포인트를 매핑합니다. 접두사는 모든 라우트 앞에 자동으로 추가됩니다.

var products = app.MapGroup("/api/products").WithTags("Products");

products.MapGet("/",     GetAll);
products.MapGet("/{id}", GetById);
products.MapPost("/",    Create);
products.MapPut("/{id}", Update);
products.MapDelete("/{id}", Delete);
// Routes: /api/products, /api/products/{id}

그룹에 인증 적용하기

그룹에서 RequireAuthorization()을 사용하면 모든 엔드포인트를 한 번에 보호할 수 있습니다. 개별 엔드포인트에서는 여전히 AllowAnonymous()로 재정의할 수 있습니다.

var adminGroup = app.MapGroup("/admin")
    .RequireAuthorization("AdminPolicy")
    .WithTags("Admin");

adminGroup.MapGet("/users",    GetAllUsers);
adminGroup.MapDelete("/users/{id}", DeleteUser);

// This one inside the group opts out
adminGroup.MapGet("/status", () => "OK").AllowAnonymous();

라우트 매개변수 제약 조건

형식 패턴으로 라우트 매개변수를 제한합니다. 라우터는 패턴과 일치하지 않는 요청을 거부하고 자동으로 404를 반환합니다.

// Only matches numeric IDs
app.MapGet("/products/{id:int}", (int id) => id);

// GUID constraint
app.MapGet("/orders/{orderId:guid}", (Guid orderId) => orderId);

// Length constraint
app.MapGet("/codes/{code:length(6)}", (string code) => code);

// Min value
app.MapGet("/page/{page:min(1)}", (int page) => page);

다양한 소스에서 바인딩하기

특성을 사용하면 다양한 소스에서 매개변수를 바인딩할 수 있습니다. 기본적으로 단순 형식은 라우트나 쿼리에서, 복합 형식은 본문에서 가져옵니다.

app.MapPost("/search", (
    [FromQuery] string q,
    [FromQuery] int page,
    [FromHeader(Name = "X-Api-Version")] string version,
    [FromBody] SearchFilters filters,
    AppDbContext db) =>
{
    // q and page from query string
    // version from request header
    // filters from JSON body
    return Results.Ok();
});

TryParse를 사용한 사용자 지정 매개변수 바인딩

라우트 또는 쿼리 매개변수로 사용하는 사용자 지정 형식에는 정적 TryParse 메서드를 구현합니다. 프레임워크가 이 메서드를 자동으로 호출하여 문자열 값을 구문 분석합니다.

public record ProductFilter(string? Category, decimal? MinPrice)
{
    public static bool TryParse(string value, out ProductFilter result)
    {
        var parts = value.Split(':');
        result = new ProductFilter(
            parts.Length > 0 ? parts[0] : null,
            parts.Length > 1 && decimal.TryParse(parts[1], out var p) ? p : null);
        return true;
    }
}

// Usage: GET /products?filter=Electronics:50
app.MapGet("/products", ([FromQuery] ProductFilter filter) => filter);

데이터 주석 유효성 검사

요청 데이터 전송 객체에 데이터 주석 특성을 지정합니다. 미니멀 API에서는 IValidatableObject 인터페이스나 유효성 검사 필터를 사용하여 유효성 검사를 실행합니다.

using System.ComponentModel.DataAnnotations;

record CreateProductRequest
{
    [Required, MaxLength(200)]
    public string Name { get; init; } = "";

    [Range(0.01, 999999)]
    public decimal Price { get; init; }

    [Range(0, int.MaxValue)]
    public int Stock { get; init; }
}

유효성 검사를 위한 엔드포인트 필터

엔드포인트 필터는 처리기 전후에 실행됩니다. 필터를 사용하여 모델 유효성 검사를 추가하고, 잘못된 요청이 비즈니스 논리에 도달하기 전에 거부할 수 있습니다.

app.MapPost("/products", CreateProduct)
   .AddEndpointFilter(async (ctx, next) =>
   {
       var req = ctx.GetArgument<CreateProductRequest>(0);
       var errors = new List<ValidationResult>();
       if (!Validator.TryValidateObject(req,
               new ValidationContext(req), errors, true))
       {
           return Results.ValidationProblem(
               errors.ToDictionary(e => e.MemberNames.First(),
                                   e => new[] { e.ErrorMessage! }));
       }
       return await next(ctx);
   });

FluentValidation 통합

복잡한 유효성 검사 규칙에는 SharpGrip.FluentValidation.AutoValidation.Endpoints 패키지와 FluentValidation을 사용하여 미니멀 API에서 유효성 검사를 자동화합니다.

public class CreateProductValidator : AbstractValidator<CreateProductRequest>
{
    public CreateProductValidator()
    {
        RuleFor(x => x.Name).NotEmpty().MaximumLength(200);
        RuleFor(x => x.Price).GreaterThan(0);
        RuleFor(x => x.Stock).GreaterThanOrEqualTo(0);
    }
}

builder.Services.AddFluentValidationAutoValidation();
builder.Services.AddValidatorsFromAssemblyContaining<CreateProductValidator>();

중첩된 라우트 그룹

라우트 그룹을 중첩하여 주문에 주문 항목이 포함되는 것과 같은 계층적 리소스를 모델링할 수 있습니다.

var api = app.MapGroup("/api").RequireAuthorization();

var orders = api.MapGroup("/orders");
orders.MapGet("/", GetAllOrders);
orders.MapGet("/{id:int}", GetOrder);

// Nested: /api/orders/{orderId}/lines
var lines = orders.MapGroup("/{orderId:int}/lines");
lines.MapGet("/",        GetOrderLines);
lines.MapPost("/",       AddOrderLine);
lines.MapDelete("/{id}", RemoveOrderLine);

실전: 버전이 지정된 API 그룹

엔드포인트를 API 버전별로 그룹화하면 인증이나 태그 구성을 중복하지 않고 여러 버전을 동시에 지원할 수 있습니다.

var v1 = app.MapGroup("/api/v1")
    .RequireAuthorization()
    .WithTags("v1");

var v2 = app.MapGroup("/api/v2")
    .RequireAuthorization()
    .WithTags("v2");

v1.MapGet("/products", GetProductsV1);
v2.MapGet("/products", GetProductsV2); // richer response

확인 문제

미니멀 API에서 MapGroup()의 목적은 무엇입니까?

복습: 라우트 그룹, 매개변수 및 유효성 검사

핵심 요점:

  • MapGroup(): 여러 엔드포인트에서 접두사와 구성을 공유합니다
  • 라우트 제약 조건(:int, :guid, :min)은 일치하지 않는 라우트를 자동으로 거부합니다
  • [FromQuery], [FromHeader], [FromBody]로 바인딩 소스를 명시합니다
  • 사용자 지정 형식에 TryParse를 구현하면 라우트 및 쿼리 바인딩이 자동으로 수행됩니다
  • 엔드포인트 필터로 유효성 검사와 같은 횡단 관심사를 처리할 수 있습니다

자주 묻는 질문

“경로 그룹, 매개 변수와 유효성 검사” 강의는 무료인가요?

네 — “경로 그룹, 매개 변수와 유효성 검사” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 C# Academy 강의 전체를 잠금 해제할 수 있습니다. C# Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“경로 그룹, 매개 변수와 유효성 검사”에서 뭘 배우나요?

MapGroup으로 엔드포인트를 구성하고 경로, 쿼리, 본문 매개 변수를 바인딩하며 데이터 주석으로 유효성을 검사합니다. 브라우저에서 직접 실행하는 실습 코드로 C# Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

C# Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 C# Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.

“경로 그룹, 매개 변수와 유효성 검사” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 C# Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 C# Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 첫 번째 Minimal API 만들기
  2. 경로 그룹, 매개 변수와 유효성 검사
  3. Minimal API의 미들웨어와 필터
  4. OpenAPI, 버전 관리와 배포
← C# Academy(으)로 돌아가기