Minimal APIのミドルウェアとフィルター
Minimal APIのパイプラインに認証、認可、例外処理、エンドポイントフィルターを追加します。
「Minimal APIのミドルウェアとフィルター」はCoddyKit上の無料C# Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC# Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C# Academyコースには全4レッスンが含まれています。
ミドルウェアとエンドポイントフィルターの違い
ASP.NET Core には、拡張性を提供する 2 つの層があります。ミドルウェアはパイプライン全体をラップし、すべてのリクエストで実行されます。一方、エンドポイントフィルターは特定のエンドポイントに対してのみ実行されます。どちらも Minimal APIs で利用できます。
Minimal APIs へのミドルウェアの追加
標準の ASP.NET Core ミドルウェアは app.Use* メソッドで追加します。実行順序は重要です。ミドルウェアは登録された順序で実行されます。
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.UseRateLimiter();
app.MapGet("/secure", () => "Protected endpoint")
.RequireAuthorization();
app.Run();インラインエンドポイントフィルター
エンドポイントフィルターは、単一のエンドポイントにスコープを限定したミドルウェアのようなものです。AddEndpointFilter を使ってフィルターをインラインで追加します。フィルターは、next を呼び出さずに結果を返すことで、処理をショートサーキットできます。
app.MapGet("/guarded", () => "Secret data")
.AddEndpointFilter(async (ctx, next) =>
{
var header = ctx.HttpContext.Request.Headers["X-Api-Key"];
if (header != "my-secret-key")
return Results.Unauthorized();
return await next(ctx); // proceed to handler
});クラスベースのエンドポイントフィルター
IEndpointFilter を実装して、再利用可能なフィルターを作成します。個々のエンドポイントまたはルートグループ全体に適用できます。
public class LoggingFilter : IEndpointFilter
{
private readonly ILogger<LoggingFilter> _logger;
public LoggingFilter(ILogger<LoggingFilter> logger) => _logger = logger;
public async ValueTask<object?> InvokeAsync(
EndpointFilterInvocationContext ctx,
EndpointFilterDelegate next)
{
_logger.LogInformation("Before: {Path}", ctx.HttpContext.Request.Path);
var result = await next(ctx);
_logger.LogInformation("After: {Path}", ctx.HttpContext.Request.Path);
return result;
}
}
// Apply to a group
app.MapGroup("/api").AddEndpointFilter<LoggingFilter>();例外処理ミドルウェア
app.UseExceptionHandler または組み込みの ProblemDetails ミドルウェアを使うと、未処理の例外を捕捉して RFC 7807 の問題詳細レスポンスを返せます。
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler();
// OR for custom logic:
app.UseExceptionHandler(errApp =>
errApp.Run(async ctx =>
{
var ex = ctx.Features.Get<IExceptionHandlerFeature>()?.Error;
ctx.Response.StatusCode = 500;
await ctx.Response.WriteAsJsonAsync(new { error = ex?.Message });
}));ショートサーキットミドルウェア
app.MapShortCircuit()(.NET 8 以降)またはフィルター内の Results.StatusCode() を使うと、パイプライン全体を実行せずにすぐレスポンスを返せます。
// Block known bad bots at the edge
app.MapGet("/robots.txt", () => "User-agent: *\nDisallow: /")
.ShortCircuit(); // .NET 8: returns response immediately
// Or in a filter:
app.MapGet("/maintenance", () => "OK")
.AddEndpointFilter((ctx, next) =>
ValueTask.FromResult<object?>(Results.StatusCode(503)));.NET 7 以降のレート制限
組み込みのレートリミッターミドルウェアは、エンドポイントを悪用から保護します。RequireRateLimiting() を使って、ポリシーをグローバルまたはエンドポイント単位で適用できます。
using System.Threading.RateLimiting;
builder.Services.AddRateLimiter(opt =>
{
opt.AddFixedWindowLimiter("fixed", o =>
{
o.PermitLimit = 10;
o.Window = TimeSpan.FromSeconds(10);
o.QueueLimit = 0;
o.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
});
opt.RejectionStatusCode = StatusCodes.Status429TooManyRequests;
});
app.UseRateLimiter();
app.MapGet("/search", Search).RequireRateLimiting("fixed");CORS の設定
サービスで CORS ポリシーを設定し、グローバルまたはエンドポイント単位で適用して、API にアクセスできるオリジンを制御します。
builder.Services.AddCors(opt =>
opt.AddPolicy("AllowFrontend", policy =>
policy.WithOrigins("https://myapp.com")
.AllowAnyHeader()
.AllowAnyMethod()));
app.UseCors("AllowFrontend");
// Or per endpoint:
app.MapGet("/public-data", () => "data")
.RequireCors("AllowFrontend");出力キャッシュミドルウェア
AddOutputCache はレスポンスをサーバー側でキャッシュします。特定のエンドポイントに適用すると、リクエストのたびにデータベースへアクセスせず、キャッシュ済みのレスポンスを返せます。
builder.Services.AddOutputCache();
app.UseOutputCache();
app.MapGet("/products", async (AppDbContext db) =>
Results.Ok(await db.Products.AsNoTracking().ToListAsync()))
.CacheOutput(p => p.Expire(TimeSpan.FromMinutes(5)));フィルターの順序とチェーン
フィルターは追加された順序で実行されます(ミドルウェアと同様に、外側が先で内側が後です)。同じエンドポイントまたはグループに複数のフィルターをチェーンできます。
app.MapPost("/orders", CreateOrder)
.AddEndpointFilter<LoggingFilter>() // runs first
.AddEndpointFilter<ValidationFilter>() // runs second
.AddEndpointFilter<AuthFilter>() // runs third
.RequireAuthorization(); // JWT checked by middleware実践:API キーミドルウェア
ヘッダーから API キーを読み取り、無効な場合は 401 でショートサーキットする、再利用可能な API キーミドルウェアです。
public class ApiKeyMiddleware
{
private readonly RequestDelegate _next;
private readonly string _expectedKey;
public ApiKeyMiddleware(RequestDelegate next, IConfiguration cfg)
{
_next = next;
_expectedKey = cfg["ApiKey"] ?? throw new Exception("ApiKey not configured");
}
public async Task InvokeAsync(HttpContext ctx)
{
if (!ctx.Request.Headers.TryGetValue("X-Api-Key", out var key)
|| key != _expectedKey)
{
ctx.Response.StatusCode = 401;
await ctx.Response.WriteAsync("Invalid API key");
return;
}
await _next(ctx);
}
}
app.UseMiddleware<ApiKeyMiddleware>();確認問題
Minimal APIs におけるミドルウェアとエンドポイントフィルターの主な違いは何ですか。
まとめ:ミドルウェアとフィルター
重要なポイント:
- ミドルウェア(UseX)は、パイプラインの登録順に従って、すべてのリクエストに対してグローバルに実行されます
- エンドポイントフィルター(AddEndpointFilter)は、特定のエンドポイントまたはグループにスコープが限定されます
- IEndpointFilter を実装すると、再利用可能で DI に対応したフィルタークラスを作成できます
- 組み込みミドルウェアには、レート制限、CORS、出力キャッシュ、例外処理があります
- フィルターの順序は重要です。ミドルウェアのようにネストされ、最初に追加したものが最も外側になります
よくある質問
「Minimal APIのミドルウェアとフィルター」レッスンは無料ですか?
はい。「Minimal APIのミドルウェアとフィルター」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C# Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C# Academyコースには全4レッスンが含まれています。
「Minimal APIのミドルウェアとフィルター」で何を学びますか?
Minimal APIのパイプラインに認証、認可、例外処理、エンドポイントフィルターを追加します。 ブラウザで直接実行するハンズオンコードでC# Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
C# Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのC# Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「Minimal APIのミドルウェアとフィルター」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このC# Academyレッスンでコードを書いて実行できますか?
はい。すべてのC# Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 初めてのMinimal APIの作成
- ルートグループ、パラメーターと検証
- Minimal APIのミドルウェアとフィルター
- OpenAPI、バージョニングとデプロイ