外部サービス

【Blazor】Swaggerを統合して簡単にAPIをテストする

swagger

Swagger とは?

Swagger は、REST API の設計やテスト、ドキュメント化ができる便利なオープンソースのツールです。

Swagger の種類は3つあります。

Swagger Editor OpenAPI 仕様を記述できるブラウザーベースのエディター
Swagger UI OpenAPI 仕様からドキュメントを生成するツール
Swagger Codegen OpenAPI 仕様からコードを生成するツール

OpenAPI 仕様とは、JSON または YAML 形式で書ける API の仕様のことで、以下のような形式となっています。

OpenAPI 仕様サンプル(長いので折りたたみ)

{
  "openapi": "3.0.1",
  "info": {
    "title": "SwaggerSampleWebAssembly.Server",
    "version": "1.0"
  },
  "paths": {
    "/WeatherForecast": {
      "get": {
        "tags": [
          "WeatherForecast"
        ],
        "parameters": [
          {
            "name": "count",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WeatherForecast"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WeatherForecast"
                  }
                }
              },
              "text/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WeatherForecast"
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "WeatherForecast": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "date-time"
          },
          "temperatureC": {
            "type": "integer",
            "format": "int32"
          },
          "summary": {
            "type": "string",
            "nullable": true
          },
          "temperatureF": {
            "type": "integer",
            "format": "int32",
            "readOnly": true
          }
        },
        "additionalProperties": false
      }
    }
  }
}

ただし、OpenAPI 仕様をゼロから書くのは大変なので、専用のエディターが用意されていたり、プログラムから自動的に生成することができたりします。

本記事で紹介するのは「Swagger UI」で、すでにあるプログラムをドキュメント化して、実際の動作も確認できるものです。

この記事では、Blazor Server と Blazor WebAssembly に Swagger を統合する方法について見ていきます。

Blazor WebAssembly に統合する方法

パッケージの追加

Blazor WebAssembly に統合するには、Server プロジェクトに Nuget パッケージを追加します。

Mac の場合は、Server プロジェクトを右クリックすると Nuget パッケージの追加メニューが出てきます。

swagger

Swashbuckle.AspNetCore を探して追加します。バージョンは最新を入れました。

swagger

プログラムの修正

お作法があり、プログラムを少し修正する必要があります。

Server プロジェクトの Startup.cs を開いて、ConfigureServices メソッドに AddSwaggerGen のメソッドを追加してください。

Server/Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddRazorPages();

    // ここを追加
    services.AddSwaggerGen();
}

さらに下の方にスクロールして、Configure メソッドに UseSwagger と UseSwaggerUI を追加します。

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseWebAssemblyDebugging();

        // ここを追加
        app.UseSwagger();
        app.UseSwaggerUI();
    }
    // 中略
}

これで最低限の準備は完了ですが、このあとの動作確認で API のパラメータがある場合を見たいので、WeatherForecastController.cs を少し修正します。

引数に count を追加して、Enumerable.Range の引数に渡すようにしました。

Server/Controllers/WeatherForecastController.cs
[HttpGet]
public IEnumerable<WeatherForecast> Get(int count)
{
    var rng = new Random();
    return Enumerable.Range(1, count).Select(index => new WeatherForecast
    {
        Date = DateTime.Now.AddDays(index),
        TemperatureC = rng.Next(-20, 55),
        Summary = Summaries[rng.Next(Summaries.Length)]
    })
    .ToArray();
}

動作確認

デバッグ実行をすると、次のようなメッセージが表示されるかもしれませんが、「インストールして信頼する」をして問題ありません。

swagger

デバッグ実行をするとホーム画面が表示されるので、「https://localhost:5001/swagger」にアクセスしてください。

すると、「https://localhost:5001/swagger/index.html」が表示されます。

ポート番号はローカル環境によって変わるかもしれませんので、デバッグ時に表示された localhost の URL に対して「/swagger」をつければよいです。

ここまでの環境構築に問題がなければ、次の画面が表示されます。

swagger

HttpGet として定義されている API が表示されていますね。

他にも API を追加すれば、どんどん表示が増えていく仕組みです。

ここで、GET の中身を開いて「Try it out」を押してみましょう。すると、パラメーターの入力ができるようになります。今回は3を入力してみました。

swagger

これで Execute ボタンを押すと、引数に3を渡して API を実行した結果が表示されるようになっています。

Code 200 で、Response body に実際の返却値が JSON 形式で表示されていることがわかります。

swagger

実際に UI を作って動作確認しなくても、Swagger UI を使うことで動作確認がかんたんにできるのは、とても便利ですね。

Blazor Server に統合する方法

パッケージの追加

Blazor Server の場合も、Blazor WebAssembly の場合と同じくプロジェクトにパッケージを追加します。

swagger

Swashbuckle.AspNetCore を探して追加します。バージョンは最新を入れました。

swagger

Controller の追加

Blazor Server ではサービスクラスが用意されており、API Controller が用意されていません。

Swagger UI は API Controller をテストするものなので、プログラムの追加が必要です。

新たにフォルダとコントローラークラスを追加しました。内容は Blazor WebAssembly のときと同じです。

WebApi/Controllers/WeatherForecastController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using SwaggerSample.Shared;
using SwaggerSample.Data;

namespace SwaggerSample.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        private readonly ILogger<WeatherForecastController> _logger;

        public WeatherForecastController(ILogger<WeatherForecastController> logger)
        {
            _logger = logger;
        }

        [HttpGet]
        public IEnumerable<WeatherForecast> Get(int count)
        {
            var rng = new Random();
            return Enumerable.Range(1, count).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            })
            .ToArray();
        }
    }
}

Startup の修正

Startup.cs に対して、Swagger のメソッドを3つ追加するのは Blazor WebAssembly と同じです。

しかし今回は Controller を追加しているので、AddControllers と MapControllers のメソッドも追加しなければ、正常に動作しません。

ちょっとしたハマりどころですので、忘れないように注意しましょう。

public void ConfigureServices(IServiceCollection services)
{
    // ここを追加
    services.AddControllers();
    services.AddRazorPages();
    services.AddServerSideBlazor();
    services.AddSingleton<WeatherForecastService>();

        // ここを追加
    services.AddSwaggerGen();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();

        // ここを追加
        app.UseSwagger();
        app.UseSwaggerUI();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }

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

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        // ここを追加
        endpoints.MapControllers();
        endpoints.MapBlazorHub();
        endpoints.MapFallbackToPage("/_Host");
    });
}
ねこじょーかー
ねこじょーかー
動作確認のイメージは、Blazor WebAssembly のセクションでご確認ください!

最後に

Swagger を統合する手順について解説しました。

Swagger UI はドキュメントとして使うにも、動作を確認して見るにも便利なツールです。

無料で使えるので、ぜひ使ってみてください。

Blazor の書籍も好評発売中!
blazor-book

入門編から EC サイトを作る応用編まで、Blazor の本を3冊執筆しました。

私が1年以上かけて学習した内容をすべて詰め込んでいるので、さらにステップアップしたい方はぜひご覧ください。