【ITニュース解説】Middleware in .Net
2025年09月13日に「Dev.to」が公開したITニュース「Middleware in .Net」について初心者にもわかりやすく解説しています。
ITニュース概要
.NETのミドルウェアは、クライアントからのリクエストやレスポンス処理に介入し、内容を整形する機能だ。認証やログ記録などに活用され、HTTPヘッダーの必須キーをチェックし、不足していればエラーを返すミドルウェアを実装できる。
ITニュース解説
Webアプリケーションがクライアントからのリクエストを受け取ってから、適切なレスポンスを返すまでの間には、様々な処理が段階的に行われる。この一連の処理の中で、共通して行われるような特定の機能を切り出して、リクエスト処理の途中に挟み込む仕組みを「ミドルウェア」と呼ぶ。ミドルウェアは、リクエストがシステムに入力されてからレスポンスが出力されるまでの間に、各処理段階で特定の機能を実行する役割を担っている。
なぜミドルウェアが必要なのか。例えば、多くのWebアプリケーションでは、どのユーザーからのリクエストなのかを確認する「認証」や、そのユーザーが特定の操作を行う権限を持っているかを確認する「認可」といった処理が必要となる。また、システムの問題を特定するために、どのリクエストがいつ、どのような経路で処理されたかを記録する「ロギング」の機能も欠かせない。これら認証、認可、ロギングといった処理は、アプリケーションのほとんどすべてのリクエストに対して適用されることが多い。もしこれらの処理を、個々のエンドポイント(特定の機能を提供するURL)ごとに記述してしまうと、同じコードが大量に複製されてしまい、コードの見通しが悪くなるだけでなく、機能の追加や変更があった場合に修正箇所が膨大になり、バグを生みやすくなる。ミドルウェアを利用することで、これらの共通処理を独立した部品として開発し、リクエストが通る「パイプライン」の適切な位置に配置できるようになる。これにより、コードの重複が減り、保守性が向上し、開発効率も上がるのだ。
記事では、.NETという開発フレームワークにおけるミドルウェアの実装方法について解説している。具体例として挙げられているのは、APIプロジェクトに対して、リクエストヘッダーに特定のキー(Client-KeyとDevice-Id)が含まれているかをチェックし、含まれていなければエラーレスポンスを返すミドルウェアだ。このミドルウェアが、実際にどのように動作するのかを見ていこう。
まず、HeaderCheckMiddlewareというクラスが作成されている。このクラスが、実際にヘッダーチェックのロジックを持つミドルウェアの本体となる。このクラスのコンストラクタには、RequestDelegate _nextという引数が渡されている。RequestDelegateは、現在のミドルウェアでの処理が完了した後、次にどのミドルウェア、または最終的なリクエストハンドラー(リクエストを処理する具体的な機能)にリクエストを渡すべきかを示す参照である。
ミドルウェアの核心となるのは、Invokeメソッドである。このメソッドは、リクエストがこのミドルウェアを通過するたびに呼び出され、HttpContextというオブジェクトを引数に受け取る。HttpContextオブジェクトは、現在のHTTPリクエストに関するあらゆる情報(リクエストヘッダー、URL、ボディなど)と、これから作成するHTTPレスポンスに関する情報を持っている。Invokeメソッドの中で、開発者はリクエストの内容を調べたり、変更したり、レスポンスを作成したりすることができる。
記事の例では、Invokeメソッド内で、まずhttpContext.Request.Headers.Keys.Contains("Client-Key")とhttpContext.Request.Headers.Keys.Contains("Device-Id")というコードを使って、リクエストヘッダーにClient-KeyとDevice-Idというキーが存在するかどうかを確認している。もし、これらのキーのどちらか、または両方が存在しない場合、if (!key1 || !key2)の条件が真となる。このとき、ミドルウェアはすぐにエラーレスポンスを返す。具体的には、httpContext.Response.StatusCode = 400;でHTTPステータスコードを「400 Bad Request」(不正なリクエスト)に設定し、await httpContext.Response.WriteAsync("Missing requeired keys !");でクライアントに対してエラーメッセージを書き込む。そして、return;が実行されることで、これ以上リクエストパイプラインの奥深くへ処理を進めることなく、その場でレスポンスをクライアントに返却する。これにより、必要なヘッダー情報がない不正なリクエストは、アプリケーションのコアなロジックに到達する前にブロックされることになる。
逆に、必要なヘッダーキーがすべて存在する場合、elseブロック(記事のコードでは//todoの部分)が実行され、その後await _next.Invoke(httpContext);が呼び出される。このawait _next.Invoke(httpContext);こそが、現在のミドルウェアでの処理を終え、リクエストとHttpContextオブジェクトを次のミドルウェアへと引き渡す重要な処理だ。このようにして、リクエストはパイプラインを順に進んでいく。
次に、このHeaderCheckMiddlewareをアプリケーションに組み込むための拡張メソッドが定義されている。MiddlewareExtensionという静的クラスに、UseHeaderCheckMiddlewareという静的メソッドが作られている。この拡張メソッドは、IApplicationBuilderインターフェースに対して、カスタムミドルウェアを簡単に登録するための便利な方法を提供する。開発者は、アプリケーションの起動時に実行されるprogram.csファイルで、app.UseHeaderCheckMiddleware();のように記述するだけで、先ほど作成したヘッダーチェックミドルウェアをリクエストパイプラインに組み込むことができる。この一行を追加するだけで、すべてのHTTPリクエストがHeaderCheckMiddlewareを通過するようになり、自動的にヘッダーチェックが行われるようになるのだ。
実際にこのミドルウェアを組み込んだアプリケーションを動かしてみると、リクエストヘッダーにClient-KeyやDevice-Idが含まれていない場合には「400 — Bad Request」というレスポンスが返される。これはミドルウェアが期待通りに動作し、不正なリクエストをブロックしたことを示している。一方、必要なヘッダーキーがすべて含まれている場合には「200 — OK」というレスポンスが返される。これはミドルウェアがチェックを通過させ、リクエストが正常に処理されたことを意味する。
このように、ミドルウェアはWebアプリケーションの共通機能をシンプルかつ効果的に管理するための強力な仕組みである。システムエンジニアにとって、アプリケーションの安定性、セキュリティ、パフォーマンスを向上させる上で、ミドルウェアの概念と実装方法を理解することは非常に重要だ。