noxi雑記

.NET、Angularまわりの小ネタブログ

ASP.NET CoreアプリでSwaggerを導入する

ASP.NET Coreで作成したアプリのWebAPIをドキュメントにまとめるのは大変です。Swaggerを使用してWebAPIのドキュメントをまとめたり、開発をサクサク進めることができます。

TL; DR

ASP.NET CoreにSwagger機能を追加する Swashbuckle.AspNetCore.Swagger ライブラリをNugetから追加してStartupに数行書くだけで手軽に既存のASP.NET CoreアプリのWebAPIをSwaggerとして公開することができます。ただしそれだけでは実用にはほど遠く、XMLドキュメントの記述とAttributeを設定することで十分なSwaggerドキュメントが出力可能です。

Swaggerの導入

Swaggerとは

SwaggerとはRestfulAPIを開発するための開発ツールフレームワークです。OpenAPI Specification(Swagger Specifications)に基づいてRestful APIのインターフェースを記述することでSwagger開発ツールを使用して様々なメリットを受けることができます(雑説明)。
例えばSwaggerの定義さえあれば簡単にモックサーバーを立てることができますし、APIにアクセスするクライアントコードを様々な言語で自動生成することもできます。

今回の環境

ASP.NET Coreプロジェクトの作成

Visual Studioから新規ASP.NET Coreのプロジェクトを作成します。新規プロジェクト作成画面で .NET Core > ASP.NET Core Web Application を選択します。

ASP.NET Coreアプリケーションの作成

続いて表示されるWebアプリケーション作成画面ではAPIを選択します。

Webアプリケーション作成画面

するとシンプルなWebAPI用のASP.NET Coreアプリケーションが作成されます。

Swashbuckleの導入

Nugetパッケージのインストール

作成されたアプリケーションにNugetでSwashbuckleを追加します。
Nugetパッケージの管理から Swashbuckle.AspNetCore を検索してインストールします。

f:id:noxi515:20180311175948p:plain

StartupにSwashbuckleを追加

SwashbuckleはNugetパッケージをインストールしただけでは有効になりません。有効にするためにはStartupにSwaggerGenミドルウェアを追加します。
プロジェクト作成時に生成されたStartup.csのConfigureServicesメソッドはこのようになっています。ここにSwaggerGenを追加します。

// 追加前
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
}

// 追加後
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    services.AddSwaggerGen(options =>
    {
        options.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
    });
}

また、ConfigureメソッドにSwaggerを追加します。

// 追加前
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseMvc();
}

// 追加後
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    // SwaggerドキュメントをJSONとして出力する設定
    app.UseSwagger();

    // Swagger UIを表示する設定
    app.UseSwaggerUI(options =>
    {
        options.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
    });

    app.UseMvc();
}

Swagger UIでWebAPIの確認

ここまでの設定を行うと、Webアプリを起動して /swagger にアクセスするとSwagger UIが表示され、WebAPI一覧を確認できます。

f:id:noxi515:20180311181936p:plain

Swagger UIを使用すると各APIを叩いてその結果をSwagger UI上で確認することもできます。任意のAPIを選択して「Try it out」を押すとUI上から叩くための項目が追加されますので、適当な値を設定してExecuteボタンを押すと実行されます。WebAPI開発時に簡単にAPIを実行することができるためとても便利です。

f:id:noxi515:20180311182110p:plain

Swaggerドキュメントの拡充

ここまではNugetからライブラリをインストールしStartupに数行追加することで、SwaggerをASP.NET Coreアプリに追加できることが分かりました。しかしAPIの一覧は確認できますが、それぞれのAPIにドキュメントが付属せず、各APIの説明やレスポンスの型等が分かりません。続いてSwaggerドキュメントを充実する手法を説明します。

XMLドキュメントの出力と読み込み

Swaggerドキュメントを充実させるためにはアプリケーションのビルド時にXMLドキュメントを出力します。Webアプリプロジェクトのプロジェクトプロパティを表示し、ビルドタブの下の方にある「XMLドキュメントファイル」を有効にします。

f:id:noxi515:20180311183711p:plain

次にStartup.csのConfigureServicesメソッドに、このファイルを読み込む設定を追加します。

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    services.AddSwaggerGen(options =>
    {
        options.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });

        // 出力したXMLドキュメントを読み込む
        options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "SwaggerApp1.xml"));
    });
}

そしてValuesControllerを開いて適当なコメントを追加します。

namespace SwaggerApp1.Controllers
{
    [Route("api/[controller]")]
    public class ValuesController : Controller
    {
        /// <summary>
        /// ここに記述したドキュメントがSwaggerから確認できます。
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

この状態でWebアプリを実行してSwagger UIを開くと、追加したコメントが表示されているのが確認できます。

f:id:noxi515:20180311185018p:plain

レスポンスのステータスコードと型

レスポンスのステータスコードと型はXMLドキュメントとAttributeをAPIメソッドに追加することでSwaggerに反映させることができます。ステータスコードを追加するには次のように <response code="200"></response> を追記します。

/// <summary>
/// ここに記述したドキュメントがSwaggerから確認できます。
/// </summary>
/// <returns></returns>
/// <response code="200">リクエスト成功時。</response>
/// <response code="403">権限が不足している場合。</response>
[HttpGet]
public IEnumerable<string> Get()
{
    return new string[] { "value1", "value2" };
}

f:id:noxi515:20180311185737p:plain

レスポンスの型を指定するには ProducesResponseTypeAttributeAPIメソッドに追加します。Visual Studioが自動で生成したValuesControllerは元々メソッドの戻りの型が IEnumerable<string> となっているためSwagger UI上でも文字配列が返ることが分かりますが、一般的には IActionResult をメソッドの返りの型として指定すると思います。その場合この属性を追加することでステータスコード毎にレスポンスの型をを指定することができます。

/// <summary>
/// ここに記述したドキュメントがSwaggerから確認できます。
/// </summary>
/// <returns></returns>
/// <response code="200">リクエスト成功時。</response>
/// <response code="403">権限が不足している場合。</response>
[HttpGet]
[ProducesResponseType(typeof(IEnumerable<string>), 200)]
[ProducesResponseType(typeof(IDictionary<string, object>), 403)]
public IActionResult Get()
{
    return Ok(new string[] { "value1", "value2" });
}

f:id:noxi515:20180311190532p:plain

レスポンスタイプの指定

レスポンスタイプが今のままでは text/plain になっています。実際にはJSONapplication/json )なので、これを変更します。変更するにはコントローラーのクラスまたはAPIメソッドに対して ProducesAttribute を追加し、レスポンスタイプを指定します。

/// <summary>
/// ここに記述したドキュメントがSwaggerから確認できます。
/// </summary>
/// <returns></returns>
/// <response code="200">リクエスト成功時。</response>
/// <response code="403">権限が不足している場合。</response>
[HttpGet]
[Produces("application/json")]
[ProducesResponseType(typeof(IEnumerable<string>), 200)]
[ProducesResponseType(typeof(IDictionary<string, object>), 403)]
public IActionResult Get()
{
    return Ok(new string[] { "value1", "value2" });
}

f:id:noxi515:20180311190923p:plain

おわりに

今回はASP.NET CoreアプリにSwaggerを導入し、WebAPIのドキュメントを手軽に出力する方法を紹介しました。Swaggerを導入すると効率的にWebAPI開発ができるため、既存のプロジェクト新規プロジェクト問わず、ぜひ導入してはいかがでしょうか。

参考

docs.microsoft.com