Choorai
Lv.3 실무 C# ASP.NET Core

ASP.NET Core로 실무 백엔드 만들기

ASP.NET Core는 Microsoft의 크로스 플랫폼 웹 프레임워크로, 대기업, 금융, 게임 분야에서 널리 사용됩니다. Minimal API 스타일로 간결하면서도 강력한 타입 시스템과 높은 성능(Kestrel)을 제공합니다.

왜 .NET인가?

  • 대기업/금융/게임 분야의 산업 표준
  • 강력한 정적 타입 시스템 (C#)
  • 높은 성능 (Kestrel 웹 서버)
  • 크로스 플랫폼 (Windows, Linux, macOS)
  • 풍부한 현업 레퍼런스와 Microsoft 지원

1. 프로젝트 생성

터미널
# .NET SDK 설치 확인
dotnet --version

# 프로젝트 생성
dotnet new webapi -n my-api --no-https
cd my-api

dotnet new webapi는 ASP.NET Core Web API 프로젝트를 생성합니다. --no-https 옵션으로 로컬 개발 시 HTTPS를 비활성화합니다.

2. 첫 API 작성

Program.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;

var builder = WebApplication.CreateBuilder(args);

// CORS 설정
builder.Services.AddCors(options =>
{
    options.AddDefaultPolicy(policy =>
    {
        policy.WithOrigins("http://localhost:5173")
              .AllowAnyHeader()
              .AllowAnyMethod()
              .AllowCredentials();
    });
});

var app = builder.Build();
app.UseCors();

app.MapGet("/health", () => Results.Ok(new { status = "healthy" }));

app.MapGet("/api/hello", (string? name) =>
    Results.Ok(new { message = $"Hello, {name ?? "World"}!" }));

app.Run();

실행

터미널
dotnet run

# 테스트 (새 터미널에서)
curl http://localhost:5000/health
curl "http://localhost:5000/api/hello?name=Choorai"

3. CRUD API 추가

Program.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;

// 모델 정의
record Project(Guid Id, string Name, string Description, DateTime CreatedAt);

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

// In-memory 저장소
var projects = new List<Project>();
var lockObj = new object();

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

// 목록 조회
api.MapGet("/", () =>
{
    lock (lockObj)
    {
        return Results.Ok(new { items = projects, total = projects.Count });
    }
});

// 단건 조회
api.MapGet("/{id:guid}", (Guid id) =>
{
    lock (lockObj)
    {
        var project = projects.FirstOrDefault(p => p.Id == id);
        return project is not null
            ? Results.Ok(project)
            : Results.NotFound(new { error = "not found" });
    }
});

// 생성
api.MapPost("/", (CreateProjectRequest req) =>
{
    var project = new Project(
        Guid.NewGuid(),
        req.Name,
        req.Description,
        DateTime.UtcNow
    );

    lock (lockObj)
    {
        projects.Add(project);
    }

    return Results.Created($"/api/v1/projects/{project.Id}", project);
});

// 수정
api.MapPut("/{id:guid}", (Guid id, UpdateProjectRequest req) =>
{
    lock (lockObj)
    {
        var index = projects.FindIndex(p => p.Id == id);
        if (index == -1)
            return Results.NotFound(new { error = "not found" });

        projects[index] = projects[index] with
        {
            Name = req.Name,
            Description = req.Description
        };

        return Results.Ok(projects[index]);
    }
});

// 삭제
api.MapDelete("/{id:guid}", (Guid id) =>
{
    lock (lockObj)
    {
        var removed = projects.RemoveAll(p => p.Id == id);
        return removed > 0
            ? Results.NoContent()
            : Results.NotFound(new { error = "not found" });
    }
});

app.Run();

// Request DTOs
record CreateProjectRequest(string Name, string Description);
record UpdateProjectRequest(string Name, string Description);

Minimal API와 record 타입

C#의 record 타입은 불변 데이터 객체를 간결하게 정의합니다. with 표현식으로 특정 필드만 변경한 새 인스턴스를 생성할 수 있습니다.

4. Docker로 배포

Dockerfile
# Build stage
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY *.csproj .
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app

# Runtime stage
FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine
WORKDIR /app
COPY --from=build /app .
ENV ASPNETCORE_URLS=http://+:8080
EXPOSE 8080
ENTRYPOINT ["dotnet", "my-api.dll"]

멀티스테이지 빌드로 SDK(~700MB)에서 런타임(~100MB)으로 줄입니다. Alpine 기반 이미지를 사용하여 크기를 최소화합니다.

터미널
# 로컬 테스트
docker build -t my-dotnet-api .
docker run -p 8080:8080 my-dotnet-api

# 이미지 크기 확인 (~100MB)
docker images my-dotnet-api

# Cloud Run 배포
gcloud run deploy my-dotnet-api \
  --source . \
  --region asia-northeast3 \
  --allow-unauthenticated \
  --min-instances 0 \
  --max-instances 1

프레임워크 비교

항목 .NET (Minimal API) Go (Chi) FastAPI
이미지 크기 ~100MB ~15MB ~200MB
Cold Start ~200ms ~100ms ~500ms
메모리 사용 ~40MB ~20MB ~80MB
학습 곡선 중간 중간 쉬움
타입 시스템 정적 정적 동적

언제 .NET을 선택할까?

.NET 추천

  • -- 대기업/금융 시스템 구축
  • -- 강력한 타입 안전성이 필요한 경우
  • -- Windows 서버 환경 또는 Azure 인프라
  • -- 게임 서버 (Unity 연동)

다른 선택 고려

  • 최소 이미지 크기 → Go
  • 빠른 프로토타입 → Hono
  • 엔터프라이즈 구조 → NestJS

마지막 업데이트: 2026년 2월 22일 · 버전: v0.0.1

피드백 보내기

입력한 내용으로 새 이슈 페이지를 엽니다.

GitHub 이슈로 보내기