NSwag と ASP.NET Core の概要

作成者: Christoph NienaberRico SuterDave Brock

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

NSwag には次の機能があります。

  • Swagger UI と Swagger Generator を利用できます。
  • 柔軟なコード生成が可能です。

NSwag では、既存の API は不要です。Swagger が組み込まれているサードパーティ製の API を使用し、クライアント実装を生成できます。 NSwag を使用すれば、開発サイクルを短縮でき、API の変更にも容易に対応できます。

パッケージ インストール

次を行うために NSwag をインストールします。

  • 実装済みの Web API に対して Swagger 仕様を生成します。
  • Web API を参照し、テストするサービスを Swagger UI に提供します。
  • Web API の API ドキュメントを追加するサービスを Redoc に提供します。

NSwag ASP.NET Core ミドルウェアを使用するには、NSwag.AspNetCore NuGet パッケージをインストールします。 このパッケージには、Swagger 仕様、Swagger UI (v2 と v3)、ReDoc UI を生成し、それらにサービスを提供するミドルウェアが含まれています。

次のいずれかの方法で NSwag NuGet パッケージをインストールします。

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

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

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

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

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

    • [ソリューション エクスプローラー]>[NuGet パッケージの管理] でプロジェクトを右クリックします。
    • パッケージ ソースを "nuget.org" に設定します。
    • 検索ボックスに「NSwag.AspNetCore」と入力します。
    • [参照] タブから "NSwag.AspNetCore" パッケージを選択して、 [インストール] をクリックします。

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

次の手順を実行することで、ASP.NET Core アプリに Swagger を追加して構成します。

  • Program.cs で OpenApi ジェネレーターをサービス コレクションに追加します。
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
builder.Services.AddOpenApiDocument();
  • また、Program.cs で、生成された OpenApi 仕様、Swagger UI、Redoc UI のために機能するミドルウェアを有効にします。
if (app.Environment.IsDevelopment())
{
    // Add OpenAPI 3.0 document serving middleware
    // Available at: http://localhost:<port>/swagger/v1/swagger.json
    app.UseOpenApi();

    // Add web UIs to interact with the document
    // Available at: http://localhost:<port>/swagger
    app.UseSwaggerUi();
}
  • アプリを起動します。 次に移動します。
    • http://localhost:<port>/swagger (Swagger UI が表示されます)。
    • http://localhost:<port>/swagger/v1/swagger.json (Swagger 仕様が表示されます)。

コード生成

次のオプションのいずれかを選択することで、NSwag のコード生成機能を活用できます。

NSwagStudio を使用したコード生成

  • NSwagStudio GitHub リポジトリの手順に従って、NSwagStudio をインストールします。 NSwag リリース ページで、インストールおよび管理者特権なしで起動できる xcopy バージョンをダウンロードできます。
  • NSwagStudio を起動し、[Swagger Specification] の URL テキスト ボックスに swagger.json ファイルの URL を入力します。 たとえば、http://localhost:5232/swagger/v1/swagger.json のようにします。
  • [Create local Copy]\(ローカル コピーの作成\) をクリックして、Swagger 仕様の JSON 表現を生成します。

NSwag Studio imports the specification and exports a CSharp Client.

  • [Outputs]\(出力\) 領域で、[CSharp Client]\(CSharp クライアント\) チェックボックスをオンにします。 ご自身のプロジェクトに応じて、 [TypeScript Client](TypeScript クライアント) または [CSharp Web API Controller](CSharp Web API コントローラー) を選択することもできます。 [CSharp Web API Controller](CSharp Web API コントローラー) を選択した場合は、逆方向の生成が行われ、サービスの仕様からサービスが再構築されます。
  • [Generate Outputs](出力の生成) をクリックすると、TodoApi.NSwag プロジェクトの完全な C# クライアントの実装が作成されます。 生成されたクライアント コードを表示するには、 [CSharp Client](CSharp クライアント) タブをクリックします。
namespace MyNamespace
{
    using System = global::System;

    [System.CodeDom.Compiler.GeneratedCode("NSwag", "14.0.1.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")]
    public partial class TodoClient
    {
    #pragma warning disable 8618 // Set by constructor via BaseUrl property
        private string _baseUrl;
    #pragma warning restore 8618 // Set by constructor via BaseUrl property
        private System.Net.Http.HttpClient _httpClient;
        private static System.Lazy<Newtonsoft.Json.JsonSerializerSettings> _settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>(CreateSerializerSettings, true);

        public TodoClient(System.Net.Http.HttpClient httpClient)
        {
            BaseUrl = "http://localhost:5232";
            _httpClient = httpClient;
        }

        private static Newtonsoft.Json.JsonSerializerSettings CreateSerializerSettings()
        {
            var settings = new Newtonsoft.Json.JsonSerializerSettings();
            UpdateJsonSerializerSettings(settings);
            return settings;
        }

        public string BaseUrl
        {
            get { return _baseUrl; }
            set
            {
                _baseUrl = value;
                if (!string.IsNullOrEmpty(_baseUrl) && !_baseUrl.EndsWith("/"))
                    _baseUrl += '/';
            }
        }
        // code omitted for brevity

ヒント

[Settings](設定) タブでの選択に基づいて、C# クライアント コードが生成されます。この設定を変更して、既定の名前空間の名前変更や同期メソッドの生成などのタスクを実行します。

  • 生成された C# コードを、API を消費するクライアント プロジェクト内のファイルにコピーします。
  • Web API の使用を開始します。
var todoClient = new TodoClient(new HttpClient());

// Gets all to-dos from the API
var allTodos = await todoClient.GetAsync();

// Create a new TodoItem, and save it via the API.
await todoClient.CreateAsync(new TodoItem());

// Get a single to-do by ID
var foundTodo = await todoClient.GetByIdAsync(1);

API ドキュメントのカスタマイズ

OpenApi には、Web API の消費を容易にする、オブジェクト モデルをドキュメント化するオプションがあります。

API 情報と説明

Program.cs で、Web API のドキュメント情報を構成し、作成者、ライセンス、説明などの詳細情報を含めるために AddOpenApiDocument を更新します。 まず、OpenApi クラスを使用するために NSwag 名前空間をインポートします。

using NSwag;

var builder = WebApplication.CreateBuilder(args);

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

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

Swagger UI with version information.

XML コメント

XML コメントを有効にするには、次の手順を実行します。

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

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

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

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

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

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

namespace NSwagSample.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

データの注釈

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

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

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

namespace NSwagSample.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 スキーマを変更します。

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

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

応答の種類の説明

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

Create アクションでは、成功すると HTTP 201 状態コードが返されます。 HTTP 400 状態コードは、POST での要求の本文が 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 応答コードを明確に記述するようになりました (また、XML コメント も表示されます)。

Swagger UI showing POST Response Class description 'Returns the newly created Todo item' and '400 - If the item is null' for status code and reason under Response Messages.

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

Redoc

Redoc は、Swagger UI の代わりとなります。 これも OpenAPI 仕様を使用して Web API のドキュメント ページを提供するため、類似しています。 違いは、Redoc UI ではドキュメントにより重点が置かれ、API をテストするための対話型 UI は提供されない点です。

Redoc を有効にするには、そのミドルウェアを Program.cs に追加します。

if (app.Environment.IsDevelopment())
{
    // Add OpenAPI 3.0 document serving middleware
    // Available at: http://localhost:<port>/swagger/v1/swagger.json
    app.UseOpenApi();

    // Add web UIs to interact with the document
    // Available at: http://localhost:<port>/swagger
    app.UseSwaggerUi();
    
    // Add ReDoc UI to interact with the document
    // Available at: http://localhost:<port>/redoc
    app.UseReDoc(options =>
    {
        options.Path = "/redoc";
    });
}

アプリケーションを実行し、http://localhost:<port>/redoc に移動して Redoc UI を表示します。

Redoc documentation for the Sample API.

作成者: Christoph NienaberRico SuterDave Brock

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

NSwag には次の機能があります。

  • Swagger UI と Swagger Generator を利用できます。
  • 柔軟なコード生成が可能です。

NSwag では、既存の API は不要です。Swagger が組み込まれているサードパーティ製の API を使用し、クライアント実装を生成できます。 NSwag を使用すれば、開発サイクルを短縮でき、API の変更にも容易に対応できます。

NSwag ミドルウェアの登録

NSwag ミドルウェアの登録でできること:

  • 実装済みの Web API に対して Swagger 仕様を生成します。
  • Web API を参照し、テストするサービスを Swagger UI に提供します。

NSwag ASP.NET Core ミドルウェアを使用するには、NSwag.AspNetCore NuGet パッケージをインストールします。 このパッケージには、Swagger 仕様、Swagger UI (v2 と v3)、ReDoc UI を生成し、それらにサービスを提供するミドルウェアが含まれています。

次のいずれかの方法で NSwag NuGet パッケージをインストールします。

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

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

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

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

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

    • [ソリューション エクスプローラー]>[NuGet パッケージの管理] でプロジェクトを右クリックします。
    • パッケージ ソースを "nuget.org" に設定します。
    • 検索ボックスに「NSwag.AspNetCore」と入力します。
    • [参照] タブから "NSwag.AspNetCore" パッケージを選択して、 [インストール] をクリックします。

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

次の手順を実行することで、ASP.NET Core アプリに Swagger を追加して構成します。

  • Startup.ConfigureServices メソッドで、必須の Swagger サービスを登録します。
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<TodoContext>(opt =>
        opt.UseInMemoryDatabase("TodoList"));
    services.AddMvc();

    // Register the Swagger services
    services.AddSwaggerDocument();
}
  • Startup.Configure メソッドで、生成された Swagger 仕様と SwaggerUI 対応のミドルウェアを有効にします。
public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles();

    // Register the Swagger generator and the Swagger UI middlewares
    app.UseOpenApi();
    app.UseSwaggerUi3();

    app.UseMvc();
}
  • アプリを起動します。 次に移動します。
    • http://localhost:<port>/swagger (Swagger UI が表示されます)。
    • http://localhost:<port>/swagger/v1/swagger.json (Swagger 仕様が表示されます)。

コード生成

次のオプションのいずれかを選択することで、NSwag のコード生成機能を活用できます。

NSwagStudio を使用したコード生成

  • NSwagStudio GitHub リポジトリの手順に従って、NSwagStudio をインストールします。 NSwag リリース ページで、インストールや管理者特権なしで起動できる xcopy バージョンをダウンロードできます。

  • NSwagStudio を起動し、 [Swagger Specification URL](Swagger 仕様 URL) テキスト ボックスに swagger.json ファイルの URL を入力します。 たとえば、「 http://localhost:44354/swagger/v1/swagger.json 」のように入力します。

  • [Create local Copy]\(ローカル コピーの作成\) をクリックして、Swagger 仕様の JSON 表現を生成します。

    Create local copy of Swagger specification

  • [Outputs]\(出力\) 領域で、[CSharp Client]\(CSharp クライアント\) チェックボックスをオンにします。 ご自身のプロジェクトに応じて、 [TypeScript Client](TypeScript クライアント) または [CSharp Web API Controller](CSharp Web API コントローラー) を選択することもできます。 [CSharp Web API Controller](CSharp Web API コントローラー) を選択した場合は、逆方向の生成が行われ、サービスの仕様からサービスが再構築されます。

  • [Generate Outputs](出力の生成) をクリックすると、TodoApi.NSwag プロジェクトの完全な C# クライアントの実装が作成されます。 生成されたクライアント コードを表示するには、 [CSharp Client](CSharp クライアント) タブをクリックします。

//----------------------
// <auto-generated>
//     Generated using the NSwag toolchain v12.0.9.0 (NJsonSchema v9.13.10.0 (Newtonsoft.Json v11.0.0.0)) (http://NSwag.org)
// </auto-generated>
//----------------------

namespace MyNamespace
{
    #pragma warning disable

    [System.CodeDom.Compiler.GeneratedCode("NSwag", "12.0.9.0 (NJsonSchema v9.13.10.0 (Newtonsoft.Json v11.0.0.0))")]
    public partial class TodoClient
    {
        private string _baseUrl = "https://localhost:44354";
        private System.Net.Http.HttpClient _httpClient;
        private System.Lazy<Newtonsoft.Json.JsonSerializerSettings> _settings;

        public TodoClient(System.Net.Http.HttpClient httpClient)
        {
            _httpClient = httpClient;
            _settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>(() =>
            {
                var settings = new Newtonsoft.Json.JsonSerializerSettings();
                UpdateJsonSerializerSettings(settings);
                return settings;
            });
        }

        public string BaseUrl
        {
            get { return _baseUrl; }
            set { _baseUrl = value; }
        }

        // code omitted for brevity

ヒント

[Settings](設定) タブでの選択に基づいて、C# クライアント コードが生成されます。この設定を変更して、既定の名前空間の名前変更や同期メソッドの生成などのタスクを実行します。

  • 生成された C# コードを、API を消費するクライアント プロジェクト内のファイルにコピーします。
  • Web API の使用を開始します。
 var todoClient = new TodoClient();

// Gets all to-dos from the API
 var allTodos = await todoClient.GetAllAsync();

 // Create a new TodoItem, and save it via the API.
var createdTodo = await todoClient.CreateAsync(new TodoItem());

// Get a single to-do by ID
var foundTodo = await todoClient.GetByIdAsync(1);

API ドキュメントのカスタマイズ

Swagger には、Web API の消費を容易にする、オブジェクト モデルをドキュメント化するオプションがあります。

API 情報と説明

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

services.AddSwaggerDocument(config =>
{
    config.PostProcess = document =>
    {
        document.Info.Version = "v1";
        document.Info.Title = "ToDo API";
        document.Info.Description = "A simple ASP.NET Core web API";
        document.Info.TermsOfService = "None";
        document.Info.Contact = new NSwag.OpenApiContact
        {
            Name = "Shayne Boyer",
            Email = string.Empty,
            Url = "https://twitter.com/spboyer"
        };
        document.Info.License = new NSwag.OpenApiLicense
        {
            Name = "Use under LICX",
            Url = "https://example.com/license"
        };
    };
});

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

Swagger UI with version information

XML コメント

XML コメントを有効にするには、次の手順を実行します。

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

データの注釈

NSwag ではリフレクションが使用されます。また、Web API アクションに推奨される戻り値の型は ActionResult<T> です。そのため、T によって定義される戻り値の型のみを推測できます。 考えられる他の戻り値の型を自動的に推測することはできません。

次に例を示します。

[HttpPost]
public ActionResult<TodoItem> Create(TodoItem item)
{
    _context.TodoItems.Add(item);
    _context.SaveChanges();

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

前のアクションでは、ActionResult<T> を返します。 アクションの内部では、CreatedAtRoute を返します。 このコントローラーには [ApiController] 属性が指定されているため、BadRequest 応答が発生する場合もあります。 詳細については、「自動的な HTTP 400 応答」を参照してください。 データ注釈を使用して、このアクションによって返される既知の HTTP 状態コードをクライアントに通知します。 次の属性でアクションをマークします。

[ProducesResponseType(StatusCodes.Status201Created)]     // Created
[ProducesResponseType(StatusCodes.Status400BadRequest)]  // BadRequest

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

Swagger ジェネレーターでは、このアクションを正確に表現できるようになりました。生成されたクライアントでは、エンドポイントの呼び出し時に受け取るものが認識されます。 すべてのアクションをこれらの属性でマークすることをお勧めします。

API アクションで返すべき HTTP 応答のガイドラインについては、RFC 9110: HTTP セマンティクス (セクション 9.3. 「Method Definitions (メソッドの定義)」) を参照してください。