最近 OpenAPI ( Swagger ) を設定するのに Swashbuckle の使い方を書いてましたが、その流れで相対パスの変更方法をメモしておきます。
相対パスの変更には2つのポイントがあります。
- Swagger UI の相対パス
- swagger.json の相対パス
それぞれ見てきます。
ちなみに Swashbuckle.AspNetCore のバージョンは現時点で最新の v5.6.3 を使っています。
Swagger UI の相対パスを変更する
Swagger UI のデフォルトの相対パスは、/swagger
( /swagger/index.html
) になっています。
これを例えば api/docs
に変更してみましょう。
私の個人的なケースを書いておくと、下図のように Azure の Web App に Web API をホストしてるんだけどその手前に Azure Front Door があり、Web API の routeing は /api/*
になっています。つまーり /api/
配下じゃないと Web API に routing されないので、今回の変更をするわけです。
Front Door の Routing rule を追加するって解決策もありますが今回だと Production 環境じゃ OpenAPI を公開しないので、DEV/Production といった環境で設定差が出るのは IaC を構築する上でもうざいので Swagger の path を変更します。
と余談なユースケースを書きましたが、設定はいたって簡単。
Startup.cs の ConfigureServices
メソッド内の UseSwaggerUI
に以下のように1行追加するだけです。
app.UseSwaggerUI(c => { c.RoutePrefix = "api/docs"; // この行を追加 c.SwaggerEndpoint("/swagger/v1/swagger.json", "AspnetCore50 Route Customize v1"); });
ローカルデバッグ時に Swagger UI を起動するように Properties >launchSettings.json を開いて launchUrl
を api/docs
に変えておきます。
デバッグすると想定通りの動作ですね。URL の相対パスが api/docs
になってます。ちなみにローカルデバッグは kestrel で、あとは Web App にデプロイして動作確認済みです。
これが多分、多くの場合やりたいことですよね。
swagger.json の相対パスを変更する
Swagger UI を構成する元の swagger.json のパスは変えなくても問題ないケースがほとんどだと思いますが、前述で書いたFront Door の routing がある構成だとデフォルトのパス ( /swagger/v1/swagger.json
) だと Web API に routing されません。
ということで、swagger.json のパスも変更します。
Startup.cs の ConfigureServices
メソッド内で、以下のようにコメントをつけた2か所を変えるだけです。ちなみに {documentName}
ってありますが、このままで大丈夫です。
// UserSwagger を以下のように変える app.UseSwagger(c => c.RouteTemplate = "api/swagger/{documentName}/swagger.json"); app.UseSwaggerUI(c => { c.RoutePrefix = "api/docs"; // SwaggerEndpoint の url を RouteTemplate の設定と同じにする c.SwaggerEndpoint("/api/swagger/v1/swagger.json", "AspnetCore50 Route Customize v1"); });
以下のドキュメントに書いてあるのですが、UseSwagger
で RouteTemplate を設定するときは、{documentName}
パラメーターは必須のようです。このパラメーターにはデフォルトだとバージョンが入ってくるようですねー 。
- https://github.com/domaindrivendev/Swashbuckle.AspNetCore#change-the-path-for-swagger-json-endpoints
もちろん swagger.json
を docs.json
とかに変えても大丈夫です。変えたければ、前述同様に2か所を変えましょう。
デバッグで実行するとこんな感じ。
コードサンプル
今回のサンプルコードの完成版はこちら:
トラブルシュート
私が遭遇したエラーの原因に戻づいて注意を書いておくと、
c.SwaggerEndpoint(
の引数のパスには、先頭に/
が必要です。ないとパスが変になってエラーになります。UseSwagger(c => c.RouteTemplate
にセットするパスは先頭に/
があってもなくても大丈夫...。
ぐぬぬってお気持ちになりました。