ASP.NET Core プロジェクトで作成した Web API のドキュメントを Swagger を使って生成したいと思います。
開発環境
Mac OS X El Capitan
Visual Studio Code
Web API アプリケーションを準備する
ASP.NET Core の Web API アプリケーションを作成済みの方はそのまま進んでください。もし作成していない場合は
- ASP.NET Core で Riot.js その1 - プロジェクトの作成
- ASP.NET Core で Riot.js その2 - Server-side
の部分を参考に実装して頂ければ幸いです。
パッケージの入手
今回は .NET で Swagger を利用するためのライブラリとして Swashbuckle を使います。
NuGet Gallery | Swashbuckle - Swagger for WebApi 5.3.2
https://www.nuget.org/packages/Swashbuckle/
project.json を開いて dependencies
に "Swashbuckle"
を追加します。
"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.0.0",
"type": "platform"
},
"Microsoft.AspNetCore.Mvc": "1.0.0",
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
"Microsoft.AspNetCore.StaticFiles": "1.0.0",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
"Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
"Microsoft.Extensions.Configuration.Json": "1.0.0",
"Microsoft.Extensions.Configuration.CommandLine": "1.0.0",
"Microsoft.Extensions.Logging": "1.0.0",
"Microsoft.Extensions.Logging.Console": "1.0.0",
"Microsoft.Extensions.Logging.Debug": "1.0.0",
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
"Swashbuckle": "6.0.0-beta901"
},
project.json を保存したら Visual Studio Code のターミナルから dotnet restore
してパッケージを取得します。
Startup.cs の変更
Startup.cs に Swagger を使うように処理を追加します。
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using AspRiotApp.Models;
namespace AspRiotApp
{
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
// リポジトリを登録
services.AddSingleton<IPersonRepository, PersonRepository>();
// SwaggerGen を追加
services.AddSwaggerGen();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseMvc();
// .tag ファイルを扱えるようにする
var provider = new FileExtensionContentTypeProvider();
provider.Mappings[".tag"] = "riot/tag";
// wwwroot/index.html を起動時に表示するようにする
app.UseDefaultFiles();
// 静的ファイルを扱えるようにする
app.UseStaticFiles(new StaticFileOptions
{
ContentTypeProvider = provider
});
// UseSwagger と UseSwaggerUi を追加
app.UseSwagger();
app.UseSwaggerUi();
}
}
}
ConfigureServices()
に services.AddSwaggerGen()
を追加して
Configure()
に app.UseSwagger()
と app.UseSwaggerUi()
を追加するだけです。
SwaggerUI を表示する
ターミナルで dotnet run
してブラウザーから swagger/ui
に接続すると SwaggerUI が表示されます。
表示されている HTTP メソッドをクリックすると詳細を見ることができます。
Try it out!
ボタンを押下することで動作の確認も可能です。
試しに POST してみます。
POST 後に GET してみると
ちゃんと反映されています。
Web API の概要も表示させる (2016/07/13 追記)
Swashbuckle は Web API の概要を XML Documentation Comments から表示するようになっています。 概要を表示させる場合は XML Documentation Comments を Swashbuckle で利用できるように XML ファイルとして出力しておく必要があります。
XML Documentation Comments を出力する
project.json の buildOptions
に "xmlDoc": true
を追加します。
"buildOptions": {
"emitEntryPoint": true,
"preserveCompilationContext": true,
"xmlDoc": true
},
以降ビルドすると XML ファイルが出力されるようになります。デフォルトだとファイルは /bin/Debug/netcoreapp1.0/[アプリケーション名].xml として出力されます。
XML Document Comments を読込むようにする
Startup.cs の ConfigureServices ()
に先ほど追加した services.AddSwaggerGen()
は引数に Action<SwaggerGenOptions>
を受取ってオプションを設定することができます。
概要を表示する場合はオプションとして IncludeXmlComments()
を追加して引数に XML ファイルのパスを指定します。
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
// リポジトリを登録
services.AddSingleton<IPersonRepository, pository>();
// XML Document のパスを取得する
var location = System.Reflection.Assembly.GetEntryAssembly().Location;
var xmlPath = location.Replace("dll", "xml");
// SwaggerGen を追加
services.AddSwaggerGen(options => {
// XML Document Comment を読込む
options.IncludeXmlComments(xmlPath);
});
}
コメントを付ける
概要を表示するコントローラにコメントを付けます。
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using AspRiotApp.Models;
namespace AspRiotApp.Controllers
{
/// <summary>
/// PersonController
/// </summary>
[Route("api/v1/[controller]")]
[Produces("application/json")]
public class PersonController : Controller
{
private IPersonRepository People { get; set; }
/// <summary>
/// Person の一覧を取得する。
/// </summary>
/// <param name="people">Person リポジトリ</param>
public PersonController(IPersonRepository people)
{
People = people;
}
/// <summary>
/// Person の一覧を取得する。
/// </summary>
/// <returns>Person の一覧</returns>
[HttpGet]
public IEnumerable<Person> Get() => People.GetAll();
/// <summary>
/// ID に紐付く Person を取得する。
/// </summary>
/// <param name="id">取得する Person の ID</param>
/// <returns>Personの一覧</returns>
[HttpGet("{id}", Name="GetPerson")]
public IActionResult Get(string id)
{
var person = People.Find(id);
if(person == null)
return NotFound();
return new ObjectResult(person);
}
/// <summary>
/// Person を作成する。
/// </summary>
/// <param name="person">作成する Person のパラメータ</param>
/// <returns>IActionResult</returns>
[HttpPost]
public IActionResult Post([FromBody]Person person)
{
if (person == null)
return BadRequest();
People.Add(person);
return new CreatedResult("GetPerson", person);
}
/// <summary>
/// ID に紐付く Person を更新する。
/// </summary>
/// <param name="id">変更する Person の ID</param>
/// <param name="person">変更する Person のパラメータ</param>
/// <returns>IActionResult</returns>
[HttpPut("{id}")]
public IActionResult Put(string id, [FromBody]Person person)
{
if (person == null || person.Id != id)
return BadRequest();
if (People.Find(id) == null)
return NotFound();
People.Update(person);
return new NoContentResult();
}
/// <summary>
/// ID に紐付く Person を削除する。
/// </summary>
/// <param name="id">削除する Person の ID</param>
[HttpDelete("{id}")]
public void Delete(string id) => People.Remove(id);
}
}
Model クラスも Swagger 上で概要を表示できるのでコメントを付けておきます。
namespace AspRiotApp.Models
{
/// <summary>
/// Person Model
/// </summary>
public class Person
{
/// <summary>
/// ID
/// </summary>
public string Id { get; set; }
/// <summary>
/// 名前
/// </summary>
public string Name { get; set; }
/// <summary>
/// 年齢
/// </summary>
public int Age { get; set; }
}
}
実行
ターミナルから dotnet run
してブラウザから swagger/ui
に接続すると概要が表示されるようになります。
パラメータの内容も反映されます。
上の画像の Model と Model Schema を選択するところで Model を選択すると、Model クラスに XML Document Comments を記述している場合はコメントが反映されます。
タイトルの変更と記事内容の修正および追記 (2016/07/13)
元々は『ASP.NET Core で作成した Web API のドキュメントを Swagger を使って生成する - ASP.NET Core で Riot.js その2.5』というタイトルで投稿した記事ですが、 内容が Riot.js に関係ない部分となっていますので Swagger についての独立した記事としてタイトルの変更と記事内容の修正および追記をおこないました。
参考
GitHub - domaindrivendev/Swashbuckle: Seamlessly adds a swagger to WebApi projects!
https://github.com/domaindrivendev/Swashbuckle
ASP.NET Core RC2 WebAPIでSwaggerを利用する - とある技術の開発日記
http://blog.hamamotsu.jp/entry/aspdotnet-core-rc2-swagger
ASP.NET Core 1.0 MVC API documentation using Swashbuckle Swagger | Software Engineering
https://damienbod.com/2015/12/13/asp-net-5-mvc-6-api-documentation-using-swagger/