Help us understand the problem. What is going on with this article?

ASP.NET Core で作成した Web API のドキュメントを Swagger を使って生成する

More than 3 years have passed since last update.

ASP.NET Core プロジェクトで作成した Web API のドキュメントを Swagger を使って生成したいと思います。

開発環境

Mac OS X El Capitan
Visual Studio Code

Web API アプリケーションを準備する

ASP.NET Core の Web API アプリケーションを作成済みの方はそのまま進んでください。もし作成していない場合は

の部分を参考に実装して頂ければ幸いです。

パッケージの入手

今回は .NET で Swagger を利用するためのライブラリとして Swashbuckle を使います。

NuGet Gallery | Swashbuckle - Swagger for WebApi 5.3.2
https://www.nuget.org/packages/Swashbuckle/

project.json を開いて dependencies"Swashbuckle" を追加します。

project.jsonの一部
  "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 を使うように処理を追加します。

Statup.cs
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 が表示されます。

スクリーンショット 2016-07-11 22.18.51.png

表示されている HTTP メソッドをクリックすると詳細を見ることができます。

スクリーンショット 2016-07-11 22.21.48.png

Try it out! ボタンを押下することで動作の確認も可能です。

スクリーンショット 2016-07-11 22.24.56.png

試しに POST してみます。

スクリーンショット 2016-07-11 22.24.12.png

POST 後に GET してみると

スクリーンショット 2016-07-11 22.25.48.png

ちゃんと反映されています。

Web API の概要も表示させる (2016/07/13 追記)

Swashbuckle は Web API の概要を XML Documentation Comments から表示するようになっています。 概要を表示させる場合は XML Documentation Comments を Swashbuckle で利用できるように XML ファイルとして出力しておく必要があります。

XML Documentation Comments を出力する

project.json の buildOptions"xmlDoc": true を追加します。

project.jsonの一部
"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 ファイルのパスを指定します。

Startup.cs
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);
    });
}

コメントを付ける

概要を表示するコントローラにコメントを付けます。

PersonController.cs
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 上で概要を表示できるのでコメントを付けておきます。

Person.csd
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 に接続すると概要が表示されるようになります。

スクリーンショット 2016-07-13 21.48.23.png

パラメータの内容も反映されます。

スクリーンショット 2016-07-13 21.48.40.png

上の画像の Model と Model Schema を選択するところで Model を選択すると、Model クラスに XML Document Comments を記述している場合はコメントが反映されます。

スクリーンショット 2016-07-13 21.56.45.png

タイトルの変更と記事内容の修正および追記 (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/

t-koyama
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした