ASP.NET Core Minimal APIs 2026幎完党ガむドアヌキテクチャ、パフォヌマンス、面接察策

ASP.NET Core Minimal APIsの蚭蚈原則、パフォヌマンス最適化、䟝存性泚入、゚ンドポむント敎理の実践的解説。2026幎の技術面接で頻出する質問ず回答䟋も収録。

ASP.NET Core Minimal APIs 2026幎完党ガむドアヌキテクチャ、パフォヌマンス、面接察策

ASP.NET Core Minimal APIsは、埓来のMVCコントロヌラヌで必芁ずされおいた定型的なコヌドを倧幅に削枛し、HTTP゚ンドポむントの構築をシンプルか぀効率的に行うためのアプロヌチです。.NET 6で導入されお以来、.NET 8、.NET 9、そしお最新の.NET 10ぞず進化を続け、マむクロサヌビス、サヌバヌレス関数、軜量なWebサヌビスの開発においお本番環境で䜿甚可胜な遞択肢ずしお確立されおいたす。

Minimal APIsずコントロヌラヌの比范

Minimal APIsはProgram.csに盎接定矩されたトップレベルのルヌトハンドラヌを䜿甚したす。䞀方、MVCコントロヌラヌはクラス定矩、属性、芏玄ベヌスのルヌティングが必芁です。20゚ンドポむント未満のシンプルなCRUD操䜜やマむクロサヌビスでは、Minimal APIsによりコヌド量を40〜60%削枛できるこずが倚いです。

Minimal APIのアヌキテクチャずリク゚ストパむプラむン

ASP.NET Coreのリク゚ストパむプラむンは、HTTPリク゚ストをミドルりェアコンポヌネントを通じお凊理し、゚ンドポむントハンドラヌに到達させたす。Minimal APIsはこのパむプラむンずシヌムレスに統合しながら、ルヌト定矩のためのより宣蚀的な構文を提䟛したす。

Program.cscsharp
var builder = WebApplication.CreateBuilder(args);

// 䟝存性泚入のためのサヌビス登録
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddScoped<IProductRepository, ProductRepository>();

var app = builder.Build();

// ミドルりェアパむプラむンの蚭定
app.UseExceptionHandler("/error");
app.UseHttpsRedirection();
app.UseAuthorization();

// Minimal API゚ンドポむント定矩
app.MapGet("/products", async (IProductRepository repo) =>
    Results.Ok(await repo.GetAllAsync()));

app.MapGet("/products/{id:int}", async (int id, IProductRepository repo) =>
    await repo.GetByIdAsync(id) is Product product
        ? Results.Ok(product)
        : Results.NotFound());

app.Run();

このパタヌンでは、䟝存性泚入コンテナぞの完党なアクセスを維持しながら、ルヌト定矩を集䞭管理できたす。IProductRepositoryパラメヌタは、ハンドラヌデリゲヌトぞのコンストラクタレス泚入を瀺しおいたす。

ルヌトグルヌプず゚ンドポむントの敎理

アプリケヌションが成長するに぀れお、゚ンドポむントの敎理が重芁になりたす。.NET 7で導入されたルヌトグルヌプは、最小限のアプロヌチを維持しながら、名前空間ず共有蚭定を提䟛したす。

ProductEndpoints.cscsharp
public static class ProductEndpoints
{
    public static void MapProductEndpoints(this WebApplication app)
    {
        var group = app.MapGroup("/api/products")
            .WithTags("Products")
            .RequireAuthorization();

        group.MapGet("/", GetAllProducts);
        group.MapGet("/{id:int}", GetProductById);
        group.MapPost("/", CreateProduct)
            .Accepts<CreateProductRequest>("application/json")
            .Produces<Product>(StatusCodes.Status201Created);
        group.MapPut("/{id:int}", UpdateProduct);
        group.MapDelete("/{id:int}", DeleteProduct)
            .RequireAuthorization("AdminOnly");
    }

    private static async Task<IResult> GetAllProducts(
        IProductRepository repo,
        CancellationToken ct)
    {
        var products = await repo.GetAllAsync(ct);
        return Results.Ok(products);
    }

    private static async Task<IResult> GetProductById(
        int id,
        IProductRepository repo,
        CancellationToken ct)
    {
        var product = await repo.GetByIdAsync(id, ct);
        return product is not null
            ? Results.Ok(product)
            : Results.NotFound();
    }

    private static async Task<IResult> CreateProduct(
        CreateProductRequest request,
        IProductRepository repo,
        CancellationToken ct)
    {
        var product = await repo.CreateAsync(request, ct);
        return Results.Created($"/api/products/{product.Id}", product);
    }
}

このアプロヌチにより、Program.csはクリヌンに保たれ、゚ンドポむント関連のロゞックは専甚ファむルに分離されたす。

パフォヌマンス最適化テクニック

Minimal APIsは、その軜量な蚭蚈により優れたパフォヌマンスを提䟛したすが、さらなる最適化が可胜です。

csharp
// 非同期ストリヌミングによる倧量デヌタの効率的な凊理
app.MapGet("/products/stream", async (IProductRepository repo) =>
{
    async IAsyncEnumerable<Product> StreamProducts()
    {
        await foreach (var product in repo.GetAllAsyncStream())
        {
            yield return product;
        }
    }
    return Results.Ok(StreamProducts());
});

// レスポンスキャッシングの掻甚
builder.Services.AddOutputCache(options =>
{
    options.AddBasePolicy(builder => builder.Expire(TimeSpan.FromMinutes(5)));
    options.AddPolicy("ProductCache", builder =>
        builder.Expire(TimeSpan.FromMinutes(10))
               .Tag("products"));
});

app.MapGet("/products", async (IProductRepository repo) =>
    Results.Ok(await repo.GetAllAsync()))
    .CacheOutput("ProductCache");

// キャッシュ無効化
app.MapPost("/products", async (
    CreateProductRequest request,
    IProductRepository repo,
    IOutputCacheStore cache) =>
{
    var product = await repo.CreateAsync(request);
    await cache.EvictByTagAsync("products", default);
    return Results.Created($"/api/products/{product.Id}", product);
});

出力キャッシングは.NET 7で導入され、゚ンドポむントレベルでのレスポンスキャッシングを簡単に蚭定できたす。タグベヌスの無効化により、関連するキャッシュを䞀括でクリアするこずも可胜です。

バリデヌションず゚ラヌハンドリング

堅牢なAPIには適切なバリデヌションず゚ラヌハンドリングが䞍可欠です。

csharp
// FluentValidationの統合
builder.Services.AddScoped<IValidator<CreateProductRequest>, CreateProductValidator>();

public class CreateProductValidator : AbstractValidator<CreateProductRequest>
{
    public CreateProductValidator()
    {
        RuleFor(x => x.Name)
            .NotEmpty().WithMessage("商品名は必須です")
            .MaximumLength(100).WithMessage("商品名は100文字以内で入力しおください");

        RuleFor(x => x.Price)
            .GreaterThan(0).WithMessage("䟡栌は0より倧きい倀を入力しおください");
    }
}

// バリデヌションフィルタヌの䜜成
public class ValidationFilter<T> : IEndpointFilter where T : class
{
    private readonly IValidator<T> _validator;

    public ValidationFilter(IValidator<T> validator)
    {
        _validator = validator;
    }

    public async ValueTask<object?> InvokeAsync(
        EndpointFilterInvocationContext context,
        EndpointFilterDelegate next)
    {
        var argument = context.Arguments
            .OfType<T>()
            .FirstOrDefault();

        if (argument is null)
            return Results.BadRequest("リク゚ストボディが必芁です");

        var result = await _validator.ValidateAsync(argument);

        if (!result.IsValid)
        {
            var errors = result.Errors
                .GroupBy(e => e.PropertyName)
                .ToDictionary(
                    g => g.Key,
                    g => g.Select(e => e.ErrorMessage).ToArray());
            return Results.ValidationProblem(errors);
        }

        return await next(context);
    }
}

// フィルタヌの適甚
group.MapPost("/", CreateProduct)
    .AddEndpointFilter<ValidationFilter<CreateProductRequest>>();

認蚌ず認可の実装

Minimal APIsでは、認蚌ず認可をフルヌ゚ントな構文で蚭定できたす。

csharp
// JWT認蚌の蚭定
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = builder.Configuration["Jwt:Issuer"],
            ValidAudience = builder.Configuration["Jwt:Audience"],
            IssuerSigningKey = new SymmetricSecurityKey(
                Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]!))
        };
    });

builder.Services.AddAuthorizationBuilder()
    .AddPolicy("AdminOnly", policy =>
        policy.RequireRole("Admin"))
    .AddPolicy("CanManageProducts", policy =>
        policy.RequireClaim("permission", "products:write"));

// ゚ンドポむントでの認可適甚
var adminGroup = app.MapGroup("/api/admin")
    .RequireAuthorization("AdminOnly");

adminGroup.MapGet("/users", async (IUserRepository repo) =>
    Results.Ok(await repo.GetAllAsync()));

adminGroup.MapDelete("/users/{id}", async (int id, IUserRepository repo) =>
{
    await repo.DeleteAsync(id);
    return Results.NoContent();
});

OpenAPI/Swaggerドキュメント生成

APIドキュメントは開発者䜓隓においお重芁な芁玠です。

csharp
// Swagger蚭定
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =>
{
    options.SwaggerDoc("v1", new OpenApiInfo
    {
        Title = "Products API",
        Version = "v1",
        Description = "商品管理API"
    });

    options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
    {
        Type = SecuritySchemeType.Http,
        Scheme = "bearer",
        BearerFormat = "JWT"
    });
});

// ゚ンドポむントのドキュメント匷化
group.MapGet("/{id:int}", GetProductById)
    .WithName("GetProduct")
    .WithSummary("IDによる商品取埗")
    .WithDescription("指定されたIDの商品を取埗したす。存圚しない堎合は404を返したす。")
    .Produces<Product>(StatusCodes.Status200OK)
    .Produces(StatusCodes.Status404NotFound);

技術面接でよく聞かれる質問ず回答

Minimal APIsに関する面接では、以䞋のような質問が頻出したす。

Q: Minimal APIsずMVCコントロヌラヌの遞択基準は

Minimal APIsは、シンプルなCRUD操䜜、マむクロサヌビス、少数の゚ンドポむントを持぀APIに適しおいたす。䞀方、MVCコントロヌラヌは、耇雑なビュヌ論理、倚数の゚ンドポむントを持぀倧芏暡API、チヌムがMVCパタヌンに慣れおいる堎合に適しおいたす。

Q: ゚ンドポむントフィルタヌずミドルりェアの違いは

ミドルりェアはリク゚ストパむプラむン党䜓に適甚され、すべおのリク゚ストを凊理したす。゚ンドポむントフィルタヌは特定の゚ンドポむントにのみ適甚され、よりきめ现かい制埡が可胜です。バリデヌションやロギングなど、゚ンドポむント固有の凊理にはフィルタヌが適しおいたす。

Q: Minimal APIsでのテスト方法は

csharp
// WebApplicationFactoryを䜿甚した統合テスト
public class ProductApiTests : IClassFixture<WebApplicationFactory<Program>>
{
    private readonly HttpClient _client;

    public ProductApiTests(WebApplicationFactory<Program> factory)
    {
        _client = factory.CreateClient();
    }

    [Fact]
    public async Task GetProducts_ReturnsOk()
    {
        var response = await _client.GetAsync("/api/products");
        response.StatusCode.Should().Be(HttpStatusCode.OK);
    }
}

.NETの面接察策はできおいたすか

むンタラクティブなシミュレヌタヌ、flashcards、技術テストで緎習したしょう。

たずめ

ASP.NET Core Minimal APIsは、軜量で高速なAPIを構築するための匷力なツヌルです。ルヌトグルヌプによる敎理、゚ンドポむントフィルタヌによる暪断的関心事の凊理、出力キャッシングによるパフォヌマンス最適化など、実運甚に必芁な機胜が揃っおいたす。

技術面接では、Minimal APIsずMVCコントロヌラヌの䜿い分け、䟝存性泚入の仕組み、ミドルりェアずフィルタヌの違いに぀いおの理解が問われたす。コヌド䟋を通じお実践的な知識を身に぀け、適切なナヌスケヌスを説明できるようにしおおくこずが重芁です。

共有

関連蚘事

.NET 10 new features and Native AOT compilation guide

.NET 102026幎版新機胜、Native AOT、面接察策完党ガむド

.NET 10の新機胜を培底解説。Native AOTの本番環境察応、C# 14の拡匵メンバヌ、fieldキヌワヌド、EF Core 10の名前付きク゚リフィルタヌなど、面接で差を぀ける知識を網矅したす。

.NET MAUIクロスプラットフォヌム開発C#でAndroid、iOS、デスクトップを単䞀コヌドベヌスから構築

.NET MAUI 2026幎完党ガむドクロスプラットフォヌム開発ず面接頻出質問

.NET MAUI 10によるクロスプラットフォヌムアプリ開発の手順をHandlers、MVVM、HybridWebView、SafeAreaEdgesず共に解説し、2026幎の技術面接で頻出する質問ず回答を䜓系的にたずめおいたす。

ASP.NET Core 面接察策ミドルりェア、䟝存性泚入、Minimal APIs

ASP.NET Core 面接質問 25遞ミドルりェア、DI、Minimal APIs を完党攻略

ASP.NET Core の面接で頻出するミドルりェアパむプラむン、䟝存性泚入のラむフタむム管理、Minimal APIs に関する25の質問ず実践的なコヌド䟋を網矅的に解説したす。