Swashbuckle と ASP.NET Core の概要

Note

Swashbuckle を使用したビルド時の OpenAPI ドキュメントの生成は、.NET 8 以降ではサポートされていません。 サポートされているビルド時の代替手段については、「Swagger/OpenAPI を使用する ASP.NET Core Web API のドキュメント」を参照してください。 .NET 8 では、実行時ドキュメントの生成は引き続きサポートされています。

Swashbuckle には 3 つの主要なコンポーネントがあります。

  • Swashbuckle.AspNetCore.Swagger: SwaggerDocument オブジェクトを JSON エンドポイントとして公開するための Swagger オブジェクト モデルとミドルウェア。

  • Swashbuckle.AspNetCore.SwaggerGen: ルート、コントローラー、モデルから直接 SwaggerDocument オブジェクトを構築する Swagger ジェネレーター。 通常、Swagger エンドポイント ミドルウェアと組み合わせて Swagger JSON を自動的に公開します。

  • Swashbuckle.AspNetCore.SwaggerUI: Swagger UI ツールの埋め込みバージョン。 Swagger JSON を解釈して、Web API の機能を説明する機能豊富かつカスタマイズ可能なエクスペリエンスを構築します。 これには、パブリック メソッド用の組み込みのテスト ハーネスが含まれます。

パッケージ インストール

Swashbuckle は、次の方法で追加できます。

  • [パッケージ マネージャー コンソール] ウィンドウから:

    • [ビュー]>[Other Windows] (その他の Windows)>[パッケージ マネージャー コンソール] に移動します。

    • .csproj ファイルが存在するディレクトリに移動します。

    • 次のコマンドを実行します。

      Install-Package Swashbuckle.AspNetCore -Version 6.5.0
      
  • [NuGet パッケージの管理] ダイアログ ボックスから:

    • [ソリューション エクスプローラー]>[NuGet パッケージの管理] でプロジェクトを右クリックします。
    • パッケージ ソースを "nuget.org" に設定します。
    • [プレリリースを含める] オプションが有効になっていることを確認します
    • 検索ボックスに「Swashbuckle.AspNetCore」と入力します。
    • [参照] タブから最新の "Swashbuckle.AspNetCore"パッケージを選択して、 [インストール] をクリックします

Swagger ミドルウェアを追加して構成する

Program.cs で Swagger ジェネレーターをサービス コレクションに追加します。

builder.Services.AddControllers();

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

前の例で示した AddEndpointsApiExplorer への呼び出しは、Minimal API でのみ必要です。 詳細については、こちらの StackOverflow の投稿を参照してください。

Program.cs でも、生成された JSON ドキュメントと Swagger UI 対応のミドルウェアを有効にします。

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

上記のコードでは、現在の環境が Development に設定されている場合にのみ Swagger ミドルウェアが追加されます。 UseSwaggerUI メソッドの呼び出しにより、Swagger UI ツールの埋め込みバージョンが有効になります。

アプリを起動し、https://localhost:<port>/swagger/v1/swagger.json に移動します。 OpenAPI 仕様 (openapi.json) に基づき、エンドポイントについて説明するドキュメントが生成され、表示されます。

Swagger UI は https://localhost:<port>/swagger にあります。 Swagger UI から API を探し、他のプログラムに組み込みます。

ヒント

アプリのルート (https://localhost:<port>/) で Swagger UI にサービスを提供するには、RoutePrefix プロパティを空の文字列に設定します。

app.UseSwaggerUI(options =>
{
    options.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
    options.RoutePrefix = string.Empty;
});

IIS やリバース プロキシを使用するディレクトリを使用している場合は、./ プレフィックスを使用して Swagger のエンドポイントを相対パスに設定します。 たとえば、./swagger/v1/swagger.json のようにします。 /swagger/v1/swagger.json を使用することで、アプリが URL の真のルート (使用されている場合は、これに加えてルート プレフィックス) にある JSON ファイルを検索するように指示されます。 たとえば、https://localhost:<port>/<virtual_directory>/<route_prefix>/swagger/v1/swagger.json の代わりに https://localhost:<port>/<route_prefix>/swagger/v1/swagger.json を使用します。

Note

既定では、Swashbuckle は、仕様 (正式には OpenAPI 仕様と呼ばれます) のバージョン 3.0 の Swagger JSON を生成して公開します。 下位互換性をサポートするために、代わりに 2.0 形式で JSON を公開することを選択できます。 この 2.0 形式は、現在 OpenAPI バージョン 2.0 をサポートしている Microsoft Power Apps や Microsoft Flow などの統合において重要です。 2\.0 形式を選択するには、Program.csSerializeAsV2 プロパティを設定します。

app.UseSwagger(options =>
{
    options.SerializeAsV2 = true;
});

カスタマイズと拡張

Swagger は、テーマに合わせてオブジェクト モデルを文書化して、UI をカスタマイズするオプションを提供します。

API 情報と説明

AddSwaggerGen メソッドに渡された構成アクションによって、作成者、ライセンス、説明などの情報が追加されます。

Program.cs で、次の名前空間をインポートし、OpenApiInfo クラスを使用します。

using Microsoft.OpenApi.Models;

OpenApiInfo クラスを使用して、UI に表示される情報を変更します。

builder.Services.AddSwaggerGen(options =>
{
    options.SwaggerDoc("v1", new OpenApiInfo
    {
        Version = "v1",
        Title = "ToDo API",
        Description = "An ASP.NET Core Web API for managing ToDo items",
        TermsOfService = new Uri("https://example.com/terms"),
        Contact = new OpenApiContact
        {
            Name = "Example Contact",
            Url = new Uri("https://example.com/contact")
        },
        License = new OpenApiLicense
        {
            Name = "Example License",
            Url = new Uri("https://example.com/license")
        }
    });
});

Swagger UI には、バージョンの情報が表示されます。

バージョン情報 (説明、作成者、ライセンス) が表示されている Swagger UI。

XML コメント

XML コメントは、次の方法で有効にすることができます。

  • ソリューション エクスプローラーでプロジェクトを右クリックし、Edit <project_name>.csproj を選択します。
  • GenerateDocumentationFile.csproj ファイルに追加します。
<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

XML コメントを有効にすると、ドキュメントに未記載のパブリック型とメンバーのデバッグ情報を提供することができます。 文書化されない型とメンバーは警告メッセージで示されます。 たとえば、次のメッセージは警告コード 1591 の違反を示します。

warning CS1591: Missing XML comment for publicly visible type or member 'TodoController'

プロジェクト全体で警告を非表示にするには、プロジェクト ファイルで無視する警告コードの一覧をセミコロン区切りで定義します。 警告コードを $(NoWarn); に追加すると、C# の既定値も適用されます。

<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
  <NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>

特定のメンバーに向けた警告のみを非表示にするには、コードを #pragma warning プリプロセッサ ディレクティブで囲みます。 この方法は、API ドキュメント経由で公開すべきではないコードの場合に役立ちます。次の例では、警告コード CS1591 が TodoContext クラス全体で無視されます。 警告コードの強制は、クラス定義の終了時に復元されます。 コンマ区切りのリストで複数の警告コードを指定します。

namespace SwashbuckleSample.Models;

#pragma warning disable CS1591
public class TodoContext : DbContext
{
    public TodoContext(DbContextOptions<TodoContext> options) : base(options) { }

    public DbSet<TodoItem> TodoItems => Set<TodoItem>();
}
#pragma warning restore CS1591

上記の手順で生成される XML ファイルを使用するように、Swagger を構成します。 Linux または Windows 以外のオペレーティング システムでは、ファイル名やパスで大文字小文字が区別されます。 たとえば、TodoApi.XML ファイルは Windows では有効ですが、Ubuntu では無効です。

builder.Services.AddSwaggerGen(options =>
{
    options.SwaggerDoc("v1", new OpenApiInfo
    {
        Version = "v1",
        Title = "ToDo API",
        Description = "An ASP.NET Core Web API for managing ToDo items",
        TermsOfService = new Uri("https://example.com/terms"),
        Contact = new OpenApiContact
        {
            Name = "Example Contact",
            Url = new Uri("https://example.com/contact")
        },
        License = new OpenApiLicense
        {
            Name = "Example License",
            Url = new Uri("https://example.com/license")
        }
    });

    // using System.Reflection;
    var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
    options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
});

前述のコードでは、Reflection を使用し、Web API プロジェクトの名前に一致する XML ファイル名が構築されます。 AppContext.BaseDirectory プロパティは、XML ファイルのパス構築に使用されます。 Swagger の一部の機能 (たとえば、入力パラメーターや HTTP メソッドのスキーマ、それぞれの属性からの応答コード) は、XML ドキュメント ファイルを使わなくても動作します。 メソッドのサマリーや、パラメーターと応答コードの記述など、ほとんどの機能には、XML ファイルの使用が必須です。

アクションにトリプル スラッシュのコメントを追加すると、セクション ヘッダーに説明が追加され、Swagger UI が向上します。 Delete アクションの上に <summary> 要素を追加します。

/// <summary>
/// Deletes a specific TodoItem.
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpDelete("{id}")]
public async Task<IActionResult> Delete(long id)
{
    var item = await _context.TodoItems.FindAsync(id);

    if (item is null)
    {
        return NotFound();
    }

    _context.TodoItems.Remove(item);
    await _context.SaveChangesAsync();

    return NoContent();
}

Swagger UI には、前述のコードの <summary> 要素の内部テキストが表示されます。

DELETE メソッドの XML コメント

UI は、生成された JSON スキーマによって決まります。

"delete": {
    "tags": [
        "Todo"
    ],
    "summary": "Deletes a specific TodoItem.",
    "parameters": [
        {
            "name": "id",
            "in": "path",
            "description": "",
            "required": true,
            "schema": {
                "type": "integer",
                "format": "int64"
            }
        }
    ],
    "responses": {
        "200": {
            "description": "Success"
        }
    }
},

Create アクション メソッドのドキュメントに <remarks> 要素を追加します。 これは、<summary> 要素で指定された情報を補足し、Swagger UI をより堅牢にします。 <remarks> 要素の内容は、テキスト、JSON、または XML で構成されます。

/// <summary>
/// Creates a TodoItem.
/// </summary>
/// <param name="item"></param>
/// <returns>A newly created TodoItem</returns>
/// <remarks>
/// Sample request:
///
///     POST /Todo
///     {
///        "id": 1,
///        "name": "Item #1",
///        "isComplete": true
///     }
///
/// </remarks>
/// <response code="201">Returns the newly created item</response>
/// <response code="400">If the item is null</response>
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> Create(TodoItem item)
{
    _context.TodoItems.Add(item);
    await _context.SaveChangesAsync();

    return CreatedAtAction(nameof(Get), new { id = item.Id }, item);
}

追加コメントで UI が向上している点にご注目ください。

追加のコメントが表示されている Swagger UI。

データの注釈

Swagger UI コンポーネントを強化するために、System.ComponentModel.DataAnnotations 名前空間にある属性でモデルをマークします。

[Required] 属性を TodoItem クラスの Name プロパティに追加します。

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace SwashbuckleSample.Models;

public class TodoItem
{
    public long Id { get; set; }

    [Required]
    public string Name { get; set; } = null!;

    [DefaultValue(false)]
    public bool IsComplete { get; set; }
}

この属性の有無は、UI 動作を変更し、基になる JSON スキーマを変更します。

"schemas": {
    "TodoItem": {
        "required": [
            "name"
        ],
        "type": "object",
        "properties": {
            "id": {
                "type": "integer",
                "format": "int64"
            },
            "name": {
                "type": "string"
            },
            "isComplete": {
                "type": "boolean",
                "default": false
            }
        },
        "additionalProperties": false
    }
},

API コントローラーに [Produces("application/json")] 属性を追加します。 その目的は、コントローラーのアクションが application/json の応答コンテンツ タイプをサポートすることを宣言することです。

[ApiController]
[Route("api/[controller]")]
[Produces("application/json")]
public class TodoController : ControllerBase
{

[メディアの種類] ドロップダウンで、コントローラーの GET アクションの既定値としてこのコンテンツ タイプが選択されます。

既定の応答のコンテンツ タイプを持つ Swagger UI

Web API のデータの注釈の使用量が多いほど、UI と API のヘルプ ページはわかりやすく便利になります。

応答の種類の説明

Web API を使用する開発者は、返される内容を最も考慮します。具体的には、応答の種類とエラー コードです (標準以外の場合)。 応答の種類とエラー コードは、XML コメントとデータ注釈に示されます。

Create アクションでは、成功すると HTTP 201 状態コードが返されます。 HTTP 400 状態コードは、投稿された要求本文が null のときに返されます。 Swagger UI に適切なドキュメントがないと、利用者にはこれらの予期される結果の知識がありません。 その問題を解決するために、次の例では強調表示された行を追加しています。

/// <summary>
/// Creates a TodoItem.
/// </summary>
/// <param name="item"></param>
/// <returns>A newly created TodoItem</returns>
/// <remarks>
/// Sample request:
///
///     POST /Todo
///     {
///        "id": 1,
///        "name": "Item #1",
///        "isComplete": true
///     }
///
/// </remarks>
/// <response code="201">Returns the newly created item</response>
/// <response code="400">If the item is null</response>
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> Create(TodoItem item)
{
    _context.TodoItems.Add(item);
    await _context.SaveChangesAsync();

    return CreatedAtAction(nameof(Get), new { id = item.Id }, item);
}

Swagger UI は、予期される HTTP 応答コードを明確に記述するようになりました。

 POST 応答クラスの説明

明示的に個別のアクションを [ProducesResponseType] で装飾する代わりに、規約を使用できます。 詳しくは、「Web API 規約を使用する」をご覧ください。

[ProducesResponseType] の装飾をサポートするために、Swashbuckle.AspNetCore.Annotations パッケージには、応答、スキーマ、およびパラメーターのメタデータを有効にし、強化する拡張機能が用意されています。

UI をカスタマイズする

既定の UI は機能も見栄えも優れています。 しかしながら、API ドキュメント ページでブランドやテーマを表す必要があります。 Swashbuckle コンポーネントをブランド化するには、静的ファイルにサービスを提供するリソースを追加し、それらのファイルをホストするフォルダー構造を構築する必要があります。

静的ファイル ミドルウェアの有効化:

app.UseHttpsRedirection();
app.UseStaticFiles();
app.MapControllers();

追加の CSS スタイルシートを挿入するには、プロジェクトの wwwroot フォルダーに追加し、ミドルウェア オプションで相対パスを指定します。

app.UseSwaggerUI(options =>
{
    options.InjectStylesheet("/swagger-ui/custom.css");
});

その他のリソース

サンプル コードを表示またはダウンロードします (ダウンロード方法)。

Swashbuckle には 3 つの主要なコンポーネントがあります。

  • Swashbuckle.AspNetCore.Swagger: SwaggerDocument オブジェクトを JSON エンドポイントとして公開するための Swagger オブジェクト モデルとミドルウェア。

  • Swashbuckle.AspNetCore.SwaggerGen: ルート、コントローラー、モデルから直接 SwaggerDocument オブジェクトを構築する Swagger ジェネレーター。 通常、Swagger エンドポイント ミドルウェアと組み合わせて Swagger JSON を自動的に公開します。

  • Swashbuckle.AspNetCore.SwaggerUI: Swagger UI ツールの埋め込みバージョン。 Swagger JSON を解釈して、Web API の機能を説明する機能豊富かつカスタマイズ可能なエクスペリエンスを構築します。 これには、パブリック メソッド用の組み込みのテスト ハーネスが含まれます。

パッケージ インストール

Swashbuckle は、次の方法で追加できます。

  • [パッケージ マネージャー コンソール] ウィンドウから:

    • [ビュー]>[Other Windows] (その他の Windows)>[パッケージ マネージャー コンソール] に移動します。

    • TodoApi.csproj ファイルが存在するディレクトリに移動します。

    • 次のコマンドを実行します。

      Install-Package Swashbuckle.AspNetCore -Version 5.6.3
      
  • [NuGet パッケージの管理] ダイアログ ボックスから:

    • [ソリューション エクスプローラー]>[NuGet パッケージの管理] でプロジェクトを右クリックします。
    • パッケージ ソースを "nuget.org" に設定します。
    • [プレリリースを含める] オプションが有効になっていることを確認します
    • 検索ボックスに「Swashbuckle.AspNetCore」と入力します。
    • [参照] タブから最新の "Swashbuckle.AspNetCore"パッケージを選択して、 [インストール] をクリックします

Swagger ミドルウェアを追加して構成する

Startup.ConfigureServices メソッドで Swagger ジェネレーターをサービス コレクションに追加します。

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<TodoContext>(opt =>
        opt.UseInMemoryDatabase("TodoList"));
    services.AddControllers();

    // Register the Swagger generator, defining 1 or more Swagger documents
    services.AddSwaggerGen();
}

Startup.Configure メソッドで、生成された JSON ドキュメントと Swagger UI 対応のミドルウェアを有効にします。

public void Configure(IApplicationBuilder app)
{
    // Enable middleware to serve generated Swagger as a JSON endpoint.
    app.UseSwagger();

    // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.)
    app.UseSwaggerUI();

    app.UseRouting();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

Note

Swashbuckle では、MVC の Microsoft.AspNetCore.Mvc.ApiExplorer に依存してルートとエンドポイントが検出されます。 プロジェクトが AddMvc を呼び出すと、ルートとエンドポイントが自動的に検出されます。 AddMvcCore を呼び出すときは、AddApiExplorer メソッドを明示的に呼び出す必要があります。 詳細については、Swashbuckle、ApiExplorer、およびルーティングに関するページを参照してください。

前の UseSwaggerUI メソッドの呼び出しにより、Swagger UI ツールの埋め込みバージョンが有効になります。 これは静的ファイル ミドルウェアによって異なります。 .NET Framework または .NET Core 1.x を対象とする場合は、Microsoft.AspNetCore.StaticFiles NuGet パッケージをプロジェクトに追加します。

アプリを起動し、http://localhost:<port>/swagger/v1/swagger.json に移動します。 OpenAPI 仕様 (openapi.json) に基づき、エンドポイントについて説明するドキュメントが生成され、表示されます。

Swagger UI は http://localhost:<port>/swagger にあります。 Swagger UI から API を探し、他のプログラムに組み込みます。

ヒント

アプリのルート (http://localhost:<port>/) で Swagger UI にサービスを提供するには、RoutePrefix プロパティを空の文字列に設定します。

app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
    c.RoutePrefix = string.Empty;
});

IIS やリバース プロキシを使用するディレクトリを使用している場合は、./ プレフィックスを使用して Swagger のエンドポイントを相対パスに設定します。 たとえば、./swagger/v1/swagger.json のようにします。 /swagger/v1/swagger.json を使用することで、アプリが URL の真のルート (使用されている場合は、これに加えてルート プレフィックス) にある JSON ファイルを検索するように指示されます。 たとえば、http://localhost:<port>/<virtual_directory>/<route_prefix>/swagger/v1/swagger.json の代わりに http://localhost:<port>/<route_prefix>/swagger/v1/swagger.json を使用します。

Note

既定では、Swashbuckle は、仕様 (正式には OpenAPI 仕様と呼ばれます) のバージョン 3.0 の Swagger JSON を生成して公開します。 下位互換性をサポートするために、代わりに 2.0 形式で JSON を公開することを選択できます。 この 2.0 形式は、現在 OpenAPI バージョン 2.0 をサポートしている Microsoft Power Apps や Microsoft Flow などの統合において重要です。 2\.0 形式を選択するには、Startup.ConfigureSerializeAsV2 プロパティを設定します。

public void Configure(IApplicationBuilder app)
{
    // Enable middleware to serve generated Swagger as a JSON endpoint.
    app.UseSwagger(c =>
    {
        c.SerializeAsV2 = true;
    });

    // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
    // specifying the Swagger JSON endpoint.
    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
    });

    app.UseRouting();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

カスタマイズと拡張

Swagger は、テーマに合わせてオブジェクト モデルを文書化して、UI をカスタマイズするオプションを提供します。

Startup クラスに、次の名前空間を追加します。

using System;
using System.Reflection;
using System.IO;

API 情報と説明

AddSwaggerGen メソッドに渡された構成アクションによって、作成者、ライセンス、説明などの情報が追加されます。

Startup クラスで、次の名前空間をインポートし、OpenApiInfo クラスを使用します。

using Microsoft.OpenApi.Models;

OpenApiInfo クラスを使用して、UI に表示される情報を変更します。

// Register the Swagger generator, defining 1 or more Swagger documents
services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo
    {
        Version = "v1",
        Title = "ToDo API",
        Description = "A simple example ASP.NET Core Web API",
        TermsOfService = new Uri("https://example.com/terms"),
        Contact = new OpenApiContact
        {
            Name = "Shayne Boyer",
            Email = string.Empty,
            Url = new Uri("https://twitter.com/spboyer"),
        },
        License = new OpenApiLicense
        {
            Name = "Use under LICX",
            Url = new Uri("https://example.com/license"),
        }
    });
});

Swagger UI には、バージョンの情報が表示されます。

バージョン情報 (説明、作成者、その他のリンク) が表示されている Swagger UI。

XML コメント

XML コメントは、次の方法で有効にすることができます。

  • ソリューション エクスプローラーでプロジェクトを右クリックし、Edit <project_name>.csproj を選択します。
  • 強調表示された行を手動で .csproj ファイルに追加します。
<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
  <NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>

XML コメントを有効にすると、ドキュメントに未記載のパブリック型とメンバーのデバッグ情報を提供することができます。 文書化されない型とメンバーは警告メッセージで示されます。 たとえば、次のメッセージは警告コード 1591 の違反を示します。

warning CS1591: Missing XML comment for publicly visible type or member 'TodoController.GetAll()'

プロジェクト全体で警告を非表示にするには、プロジェクト ファイルで無視する警告コードの一覧をセミコロン区切りで定義します。 警告コードを $(NoWarn); に追加すると、C# の既定値も適用されます。

<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
  <NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>

特定のメンバーに向けた警告のみを非表示にするには、コードを #pragma warning プリプロセッサ ディレクティブで囲みます。 この方法は、API ドキュメント経由で公開すべきではないコードの場合に役立ちます。次の例では、警告コード CS1591 が Program クラス全体で無視されます。 警告コードの強制は、クラス定義の終了時に復元されます。 コンマ区切りのリストで複数の警告コードを指定します。

namespace TodoApi
{
#pragma warning disable CS1591
    public class Program
    {
        public static void Main(string[] args) =>
            BuildWebHost(args).Run();

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .Build();
    }
#pragma warning restore CS1591
}

上記の手順で生成される XML ファイルを使用するように、Swagger を構成します。 Linux または Windows 以外のオペレーティング システムでは、ファイル名やパスで大文字小文字が区別されます。 たとえば、TodoApi.XML ファイルは Windows では有効ですが、Ubuntu では無効です。

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<TodoContext>(opt =>
        opt.UseInMemoryDatabase("TodoList"));
    services.AddControllers();

    // Register the Swagger generator, defining 1 or more Swagger documents
    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo
        {
            Version = "v1",
            Title = "ToDo API",
            Description = "A simple example ASP.NET Core Web API",
            TermsOfService = new Uri("https://example.com/terms"),
            Contact = new OpenApiContact
            {
                Name = "Shayne Boyer",
                Email = string.Empty,
                Url = new Uri("https://twitter.com/spboyer"),
            },
            License = new OpenApiLicense
            {
                Name = "Use under LICX",
                Url = new Uri("https://example.com/license"),
            }
        });

        // Set the comments path for the Swagger JSON and UI.
        var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
        var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
        c.IncludeXmlComments(xmlPath);
    });
}

前述のコードでは、Reflection を使用し、Web API プロジェクトの名前に一致する XML ファイル名が構築されます。 AppContext.BaseDirectory プロパティは、XML ファイルのパス構築に使用されます。 Swagger の一部の機能 (たとえば、入力パラメーターや HTTP メソッドのスキーマ、それぞれの属性からの応答コード) は、XML ドキュメント ファイルを使わなくても動作します。 メソッドのサマリーや、パラメーターと応答コードの記述など、ほとんどの機能には、XML ファイルの使用が必須です。

アクションにトリプル スラッシュのコメントを追加すると、セクション ヘッダーに説明が追加され、Swagger UI が向上します。 Delete アクションの上に <summary> 要素を追加します。

/// <summary>
/// Deletes a specific TodoItem.
/// </summary>
/// <param name="id"></param>        
[HttpDelete("{id}")]
public IActionResult Delete(long id)
{
    var todo = _context.TodoItems.Find(id);

    if (todo == null)
    {
        return NotFound();
    }

    _context.TodoItems.Remove(todo);
    _context.SaveChanges();

    return NoContent();
}

Swagger UI には、前述のコードの <summary> 要素の内部テキストが表示されます。

DELETE メソッドの XML コメント

UI は、生成された JSON スキーマによって決まります。

"delete": {
    "tags": [
        "Todo"
    ],
    "summary": "Deletes a specific TodoItem.",
    "operationId": "ApiTodoByIdDelete",
    "consumes": [],
    "produces": [],
    "parameters": [
        {
            "name": "id",
            "in": "path",
            "description": "",
            "required": true,
            "type": "integer",
            "format": "int64"
        }
    ],
    "responses": {
        "200": {
            "description": "Success"
        }
    }
}

Create アクション メソッドのドキュメントに <remarks> 要素を追加します。 これは、<summary> 要素で指定された情報を補足し、Swagger UI をより堅牢にします。 <remarks> 要素の内容は、テキスト、JSON、または XML で構成されます。

/// <summary>
/// Creates a TodoItem.
/// </summary>
/// <remarks>
/// Sample request:
///
///     POST /Todo
///     {
///        "id": 1,
///        "name": "Item1",
///        "isComplete": true
///     }
///
/// </remarks>
/// <param name="item"></param>
/// <returns>A newly created TodoItem</returns>
/// <response code="201">Returns the newly created item</response>
/// <response code="400">If the item is null</response>            
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<TodoItem> Create(TodoItem item)
{
    _context.TodoItems.Add(item);
    _context.SaveChanges();

    return CreatedAtRoute("GetTodo", new { id = item.Id }, item);
}

追加コメントで UI が向上している点にご注目ください。

追加のコメントが表示されている Swagger UI。

データの注釈

Swagger UI コンポーネントを強化するために、System.ComponentModel.DataAnnotations 名前空間にある属性でモデルをマークします。

[Required] 属性を TodoItem クラスの Name プロパティに追加します。

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace TodoApi.Models
{
    public class TodoItem
    {
        public long Id { get; set; }

        [Required]
        public string Name { get; set; }

        [DefaultValue(false)]
        public bool IsComplete { get; set; }
    }
}

この属性の有無は、UI 動作を変更し、基になる JSON スキーマを変更します。

"definitions": {
    "TodoItem": {
        "required": [
            "name"
        ],
        "type": "object",
        "properties": {
            "id": {
                "format": "int64",
                "type": "integer"
            },
            "name": {
                "type": "string"
            },
            "isComplete": {
                "default": false,
                "type": "boolean"
            }
        }
    }
},

API コントローラーに [Produces("application/json")] 属性を追加します。 その目的は、コントローラーのアクションが application/json の応答コンテンツ タイプをサポートすることを宣言することです。

[Produces("application/json")]
[Route("api/[controller]")]
[ApiController]
public class TodoController : ControllerBase
{
    private readonly TodoContext _context;

[応答コンテンツ タイプ] ドロップダウンがコント ローラーの GET 操作の既定値としてこのコンテンツ タイプを選択します。

[応答コンテンツ タイプ] が既定の Swagger UI。

Web API のデータの注釈の使用量が多いほど、UI と API のヘルプ ページはわかりやすく便利になります。

応答の種類の説明

Web API を使用する開発者は、返される内容を最も考慮します。具体的には、応答の種類とエラー コードです (標準以外の場合)。 応答の種類とエラー コードは、XML コメントとデータ注釈に示されます。

Create アクションでは、成功すると HTTP 201 状態コードが返されます。 HTTP 400 状態コードは、投稿された要求本文が null のときに返されます。 Swagger UI に適切なドキュメントがないと、利用者にはこれらの予期される結果の知識がありません。 その問題を解決するために、次の例では強調表示された行を追加しています。

/// <summary>
/// Creates a TodoItem.
/// </summary>
/// <remarks>
/// Sample request:
///
///     POST /Todo
///     {
///        "id": 1,
///        "name": "Item1",
///        "isComplete": true
///     }
///
/// </remarks>
/// <param name="item"></param>
/// <returns>A newly created TodoItem</returns>
/// <response code="201">Returns the newly created item</response>
/// <response code="400">If the item is null</response>            
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<TodoItem> Create(TodoItem item)
{
    _context.TodoItems.Add(item);
    _context.SaveChanges();

    return CreatedAtRoute("GetTodo", new { id = item.Id }, item);
}

Swagger UI は、予期される HTTP 応答コードを明確に記述するようになりました。

POST 応答クラスの説明

ASP.NET Core 2.2 以降では、明示的に個別のアクションを [ProducesResponseType] で装飾する代わりに、規約を使用できます。 詳しくは、「Web API 規約を使用する」をご覧ください。

[ProducesResponseType] の装飾をサポートするために、Swashbuckle.AspNetCore.Annotations パッケージには、応答、スキーマ、およびパラメーターのメタデータを有効にし、強化する拡張機能が用意されています。

UI をカスタマイズする

既定の UI は機能も見栄えも優れています。 しかしながら、API ドキュメント ページでブランドやテーマを表す必要があります。 Swashbuckle コンポーネントをブランド化するには、静的ファイルにサービスを提供するリソースを追加し、それらのファイルをホストするフォルダー構造を構築する必要があります。

.NET Framework または .NET Core 1.x を対象としている場合、プロジェクトに Microsoft.AspNetCore.StaticFiles NuGet パッケージを追加します。

<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0" />

.NET Core 2.x を対象とし、メタパッケージを使用している場合、前述の NuGet パッケージが既にインストールされています。

静的ファイル ミドルウェアの有効化:

public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles();

    // Enable middleware to serve generated Swagger as a JSON endpoint.
    app.UseSwagger();

    // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
    // specifying the Swagger JSON endpoint.
    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
    });

    app.UseRouting();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

追加の CSS スタイルシートを挿入するには、プロジェクトの wwwroot フォルダーに追加し、ミドルウェア オプションで相対パスを指定します。

app.UseSwaggerUI(c =>
{
     c.InjectStylesheet("/swagger-ui/custom.css");
}

その他のリソース