読者です 読者をやめる 読者になる 読者になる

あれとアレは混ぜるな危険

日々精進をしているふり

Swashbuckle で Swagger を使うときの逆引き的なもの

どうもどうも、はるたまです。シルバーウィークですね。

最近、巷では Web API のドキュメントを Swagger で書くのが流行ってますね。Azure 界隈でも Web Apps は Swagger 活用している感じで、Logic Apps では必須になっていたりもします。
.NET のアプリケーションで Swagger といえば Swashbuckle なわけですが、ドキュメントを書こうとしたときにちょっと困っちゃうときがあると思いますので、率先して地雷を踏んできた結果をここに書き残しておきます。

前提条件

今回は、Azure Logic Apps のテンプレートでプロジェクトを作成しています。

作成されたプロジェクトには Swashbuckle があらかじめ NuGet でインストールされているので、最新の状態にアップデートしておきます。

今回は 5.2.1 がインストールされた状態になりますので、ここからスタートです。

FromUrl が指定された引数を必須にしたくない

URL パラメーターで受ける引数を作るために FromUri 属性をつけた引数をを持つ API を作成してみます。

        public IEnumerable<string> Get([FromUri] string someValue)
        {
            return new string[] { "value1", "value2" };
        }

これを Swagger で見ると

作成した値は「必須」になってしまいます。こうなると Swagger UI からこの API をテストするときに値を必ず設定しないと、エラーになってリクエストを投げてくれません。
URL パラメーターで受ける値は多くの場合に必須ではない値になると思いますが、こんな時は

        public IEnumerable<string> Get([FromUri] string someValue = "")
        {
            return new string[] { "value1", "value2" };
        }

このようにして、引数に対してデフォルト値を設定しておきます。こうすると Swagger UI で見た結果が

「required」がとれていますね。

レスポンスのステータスコードに対してドキュメントを書きたい

クライアントに レスポンスを返す際に 200 OK 以外のステータスでレスポンスを返す場合、Swashbuckle.Swagger.Annotations 名前空間にある SwaggerResponseAttribute クラスを使ってステータスコードに対してドキュメントを書くことができます。

        [SwaggerResponse(HttpStatusCode.NotFound, Description = "何もなければ404ですよ")]
        // GET api/values
        public IEnumerable<string> Get([FromUri] string someValue = "")
        {
            return new string[] { "value1", "value2" };
        }

こんな感じで Swagger UI から見ると

という感じで、ステータスコードが追加できましたね。

クラスを引数で受ける場合にドキュメントが表示されるようにしたい

Post や Put の際には引数にクラスを指定して、リクエストの Body で送られてきたものを、こんな感じで受け取りますね。

    /// <summary>
    /// これがAPIの実体なのです
    /// </summary>
    public class ValuesController : ApiController
    {
        /// <summary>
        /// Postされると動くらしいよ
        /// </summary>
        /// <param name="value">値は何か知らない</param>
        public void Post([FromBody]Punipuni value)
        {
        }
    }

    /// <summary>
    /// 値を受けるためのクラス
    /// </summary>
    public class Punipuni
    {
        /// <summary>
        /// よく分かんないけど何か
        /// </summary>
        public string MyProperty { get; set; }
    }

この時に XML ドキュメントが出力されていればここにコメントの内容を表示したいのが人情というものですが、デフォルトでは表示されません。

これを表示させるためには、App_Start\SwaggerConfig.cs の同じような場所にこんなことを書いておきましょう。

// If you annonate Controllers and API Types with
// Xml comments (http://msdn.microsoft.com/en-us/library/b2s063f7(v=vs.110).aspx), you can incorporate
// those comments into the generated docs and UI. You can enable this by providing the path to one or
// more Xml comment files.
//
//c.IncludeXmlComments(GetXmlCommentsPath());
c.IncludeXmlComments(string.Format(@"{0}\bin\WebApplication1.XML", System.AppDomain.CurrentDomain.BaseDirectory));

もうちょっと気の利いたやり方はあるかもしれませんが、こんな感じで XML ドキュメントを指定しておくと

こんな感じで表示させることができます。
Web API の引数で受けるクラスが別のアセンブリで定義されている場合は XML ドキュメントも別ファイルで出力されるわけですが、IncludeXmlComments() は複数回呼んでも大丈夫です。
必要な分だけ呼んで XML ドキュメントを追加しましょう。