ASP.NET Core Web API 프레임워크 비교: Minimal API, MVC, FastEndpoints

ASP.NET Core를 활용하여 Web API를 개발할 때, 다양한 방식으로 API를 설계할 수 있습니다.
이번 글에서는 대표적인 Minimal API, MVC 기반 Web API, FastEndpoints 프레임워크를 비교하여 어떤 방식이 어떤 상황에 적합한지 살펴보겠습니다.

1. Minimal API

Minimal APIASP.NET Core 6부터 도입된 경량화된 API 방식으로, 컨트롤러 없이 간단한 코드로 API를 작성할 수 있습니다.

특징

:white_check_mark: Controller 없이 Program.cs에서 직접 엔드포인트 정의
:white_check_mark: 코드가 간결하여 빠르게 개발 가능
:white_check_mark: 작은 규모의 서비스나 빠른 프로토타이핑에 적합

예제 코드

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/api/hello", () => "Hello, Minimal API!");

app.Run();

2. MVC 기반 Web API (Controller 사용)

전통적인 방식의 Web API 개발 방식으로, Controller 클래스를 활용하여 API를 구성합니다.

특징

:white_check_mark: Controller 단위로 API를 분리하여 유지보수 용이
:white_check_mark: [ApiController] 속성을 사용하여 자동 검증, 모델 바인딩 등 기능 활용 가능
:white_check_mark: 중·대형 규모의 프로젝트에서 선호되는 방식

예제 코드

[ApiController]
[Route("api/[controller]")]
public class HelloController : ControllerBase
{
    [HttpGet]
    public IActionResult Get() => Ok("Hello, MVC API!");
}

3. FastEndpoints

FastEndpoints는 Minimal API보다 구조적인 설계를 가능하게 하면서도 MVC보다 가벼운 Web API 프레임워크입니다.

특징

:white_check_mark: Minimal API처럼 컨트롤러 없이 엔드포인트 단위로 동작
:white_check_mark: 요청/응답 모델을 명확하게 정의 가능
:white_check_mark: 성능이 뛰어나고 유지보수가 쉬운 방식

예제 코드

public class HelloEndpoint : Endpoint<EmptyRequest, string>
{
    public override void Configure()
    {
        Get("/api/hello");
        AllowAnonymous();
    }

    public override async Task HandleAsync(EmptyRequest req, CancellationToken ct)
    {
        await SendAsync("Hello, FastEndpoints!");
    }
}

:pushpin: 정리: 어떤 방식을 선택할까?

프레임워크 특징 적합한 경우
Minimal API 간결한 코드, 빠른 개발 작은 프로젝트, 간단한 API
MVC 기반 API 컨트롤러 기반, 유지보수 용이 중·대형 프로젝트, RESTful API
FastEndpoints Minimal API + 구조적 설계 빠르고 가벼운 API

프로젝트의 규모와 요구사항에 맞춰 적절한 방식을 선택하면, 효율적이고 유지보수하기 쉬운 Web API를 개발할 수 있습니다. :rocket:

3개의 좋아요

Milan Jovanović는 ASP.NET Core에서 Minimal API를 자동으로 등록하는 방법을 소개합니다. 기존에는 app.MapGet, app.MapPost 등을 사용해 각 엔드포인트를 수동으로 등록해야 했지만, 이를 자동화하면 코드 중복을 줄이고 유지보수를 용이하게 할 수 있습니다.milanjovanovic.tech

Jovanović는 IEndpoint라는 인터페이스를 정의하여 각 엔드포인트를 하나의 클래스로 캡슐화합니다. 각 클래스는 MapEndpoint 메서드를 구현하여 IEndpointRouteBuilder를 통해 엔드포인트를 등록합니다. 이후 리플렉션을 사용해 어셈블리를 스캔하여 IEndpoint를 구현한 클래스를 찾아 의존성 주입 컨테이너에 등록합니다.milanjovanovic.tech+1milanjovanovic.tech+1

이러한 방식은 엔드포인트를 독립적인 구성 요소로 취급하여 코드의 응집도를 높이고, 수동 등록의 번거로움을 제거합니다. 또한, 프로젝트가 확장되더라도 구조를 유지하기 용이합니다.

이 접근 방식은 ‘수직 슬라이스(Vertical Slices)’ 아키텍처와 잘 맞아떨어지며, 각 엔드포인트를 독립적인 모듈로 관리할 수 있게 해줍니다.milanjovanovic.tech


// program.cs
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Services.AddEndpoints(typeof(Program).Assembly);

WebApplication app = builder.Build();

ApiVersionSet apiVersionSet = app.NewApiVersionSet()
    .HasApiVersion(new ApiVersion(1))
    .ReportApiVersions()
    .Build();

RouteGroupBuilder versionedGroup = app
    .MapGroup("api/v{version:apiVersion}")
    .WithApiVersionSet(apiVersionSet);

app.MapEndpoints(versionedGroup);

app.Run();
// IEndpoint.cs
public interface IEndpoint
{
    void MapEndpoint(IEndpointRouteBuilder app);
}
// *Endpoint.cs
public class HelloEndpoint : IEndpoint
{
    public void MapEndpoint(IEndpointRouteBuilder app)
    {
        app.MapGet("/hello", () => "Hello, Minimal API!");
    }
}
1개의 좋아요