読者です 読者をやめる 読者になる 読者になる

miso_soup3 Blog

主に ASP.NET 関連について書いています。

Swagger を使った ASP.NET Web API のドキュメント生成

ASP.NET Web API

追記:この記事はバージョンが古いものです。より新しい情報について Swagger 2.0 に対応した ASP.NET Web API のドキュメントを作成する こちらをご覧ください。

ASP.NET Advent Calendar 2014 17 日目 の記事です。前回は iwate さんの ASP.NETプロジェクトからDBコンテキストを切り離してマイグレーションする です。

この記事では、Swagger を使った ASP.NET Web API のドキュメントを生成する方法について書きます。

f:id:miso_soup3:20141217231251p:plain

ASP.NET Web API のドキュメント生成といえば、NuGet Package「Microsoft.AspNet.WebApi.HelpPage」を使う方法 がありますが、やや欠点があります。
その欠点をカバーできる Swagger の概要を確認した後、実際に ASP.NET Web API でドキュメントを生成してみます。

目次
  • Microsoft.AspNet.WebApi.HelpPage で足りないこと
  • Swagger とは
  • Swagger を使って ASP.NET Web API のドキュメントを生成する手順
  • 最後に

Microsoft.AspNet.WebApi.HelpPage で足りないこと

f:id:miso_soup3:20141217231613p:plain

上のスクリーンは、NuGet Package「Microsoft.AspNet.WebApi.HelpPage」で生成されたドキュメントです。このパッケージの利用についてはここでは省きます。手順については Creating Help Pages for ASP.NET Web API に載っています。

このパッケージのメリットは

  • 実装コードと同期している
  • XML コメントが適用される
  • ドキュメント、HTML、共にカスタマイズが十分に可能
  • サンドボックスとして API を試すこともできる

等々と申し分ないほど充実したパッケージなのですが、

  • ドキュメントが ASP.NET MVC によって生成される

という面があります。

これで何が困るかというと、

  • ASP.NET MVC に依存する=IIS 以外の環境でホストできない
    • (一方の ASP.NET Web API はセルフホストが可能なのに)
  • 機械的に API を理解することができない
    • サーバー(ASP.NET MVC)にアクセスしてレスポンスが返ってくるまで、ドキュメントを確認できない
  • 第三者には、ネット越しでないとドキュメントを提供できない

といった、B to B でありがちなケースで困ります。そこで Swagger の出番です。

Swagger とは

Swagger とは、RESTful API のドキュメントや説明の際に利用されるための、仕様とフレームワークです。実態は、GitHub swagger-spec で公開されている仕様・ツールの総称です。

Swagger | The World's Most Popular Framework for APIs.
https://helloreverb.com/developers/swagger

Swagger サイトにあるデモページから、ドキュメントを試すことが出来ます。下の図はそのドキュメントの画像です。

f:id:miso_soup3:20141217231938p:plain

f:id:miso_soup3:20141217231944p:plain

このドキュメントは Swagger UI という Swagger のツールの一つにすぎません。Swagger の本質は、「RESTful API をどのように説明するか―そのドキュメントフォーマットの標準を定義する」ことにあります。言わば“仕様です“。

次の図は、Swagger でのドキュメント提供の概要図です。

f:id:miso_soup3:20141217232037p:plain

真ん中のオレンジの Json ファイル(Swagger Spec Files)が、Swagger の仕様に準じた API のドキュメントになります。Swagger が有効な RESTful API アプリケーションは、この Json ファイルを提供する必要があります。
そして、クライアント側の Swagger UI が、その Json ファイルを参照し、先ほどのデモサイトのようにドキュメントサイトを提供します。

Swagger にはこのほかにも以下のようなツールがあります。

  • swagger-codegen
    • Json ファイルからクライアントコードを生成する
  • swagger-editor
    • YAML で API のドキュメントを記述し、リアルタイムで Swagger UI をプレビューできる。また、YAML からJson ファイル(Swagger Spec Files)を出力できる。
言語、プラットフォームに依存しない

一度、Json ファイルに API のドキュメントを落とし込むことにより、クライアント側・サーバー側は特定のプラットフォームに依存することはありません。
現に Swagger のプロジェクトには、Go, Java, JavaScript, .NET, Node.js, Perl, PHP, Python, Ruby, Scala… と各種のツールが案内されています。
つまり、RESTful API がどのような言語で実装されていても、Json ファイルを出力する SDK ツールを使用すれば Swagger に対応できます。

Swagger UI も同じように、HTML, CSS, JavaScript のみで構成されているので、任意の Web ホストを選択できます。
その HTML ファイル群は、GitHub Swagger UI の dist フォルダ内にありますので、実際にローカルに落として「index.html」をブラウザで開けば Swagger UI を展開できます。
(Swagger UI の開発は CoffieScript で行われています)

次の図は、Json ファイル(Swagger Spec Files)の例です。

f:id:miso_soup3:20141217232131p:plain

Swagger を使って ASP.NET Web API のドキュメントを生成する手順

ここでは、ASP.NET Web API に Swagger を追加するためのライブラリ「Swashbuckle」を使って、ドキュメントを生成してみます。
Swashbuckle は version 4.0 からセルフホストに対応しています。せっかくなので、ASP.NET Web API もドキュメントも OWIN のセルフホスト上で構築してみます。

Swashbuckle の仕事は、

  • ASP.NET Web API から Json ファイル(Swagger Spec Files)を生成し提供すること
  • Swagger UI を提供すること。(Swagger UI の HTML 等 は Swashbuckle の dll 内に組み込まれている)

です。

GitHub にサンプルを up しておきました。

OWIN のセルフホストASP.NET Web API の用意

Visual Studio 2013 から、「ファイル」>「新規作成」>「プロジェクト」で「コンソールアプリケーション」を選択します。

f:id:miso_soup3:20141217232244p:plain

プロジェクト作成後、次の NuGet Packageをインストールします。

プロジェクトに「Startup.cs」を追加します。ソリューションエクスプローラーから、プロジェクトを右クリック>「追加」>「新しい項目」で「OWIN Startup」クラスを選択します。

f:id:miso_soup3:20141217232325p:plain

以下を参照して Startup.cs にコードを記述します。

using Microsoft.Owin;
using Owin;
using System.Web.Http;
using Swashbuckle.Application;

[assembly: OwinStartup(typeof(MyOwinHostApp.Startup))]

namespace MyOwinHostApp
{
	public class Startup
	{
		public void Configuration(IAppBuilder app)
		{
			HttpConfiguration config = new HttpConfiguration();

			//Swashbuckle の設定
			Swashbuckle.Bootstrapper.Init(config);
			SwaggerSpecConfig.Customize(c =>
			{
				var xmlPath = System.String.Format(@"{0}\MyOwinHostApp.XML", System.AppDomain.CurrentDomain.BaseDirectory);
				// Self-host でない場合は HttpContext.Current.Server.MapPath("~/bin/MyOwinHostApp.XML");

				c.IncludeXmlComments(xmlPath);
			});

			// ASP.NET Web API のルーティング設定
			config.Routes.MapHttpRoute(
				name: "DefaultApi",
				routeTemplate: "api/{controller}/{id}",
				defaults: new { id = RouteParameter.Optional }
			);

			app.UseWebApi(config);
		}
	}
}

「Program.cs」を開き、以下を参照してコードを記述します。

using Microsoft.Owin.Hosting;
using System;
using System.Net.Http;

namespace MyOwinHostApp
{
	class Program
	{
		static void Main(string[] args)
		{
			string baseAddress = "http://localhost:9000/";

			using (WebApp.Start<Startup>(url: baseAddress))
			{
				HttpClient client = new HttpClient();

				var response = client.GetAsync(baseAddress + "api/users").Result;

				Console.WriteLine(response);
				Console.WriteLine(response.Content.ReadAsStringAsync().Result);

				Console.ReadLine();
			}
		}
	}
}
ApiController クラスの追加

ASP.NET Web API のコントローラーを適当に追加します。
コントローラーであれば何でも良いのですが、ここでは以下のようにファイルを追加しました。
同じようにする場合はGitHubサンプルからコピーしてください。

  • Controllers フォルダを作成
    • UserController.cs を追加
  • Models フォルダを作成
    • Tag.cs, User.cs を追加

追加後のプロジェクト構成は次のようになります。

f:id:miso_soup3:20141217232409p:plain

XML コメントの設定

Swashbuckle は XML コメントも参照します。

Api Controller の任意のメソッドにて、適当にコメントを記述します。

f:id:miso_soup3:20141217232438p:plain

プロジェクトを右クリックし、「プロパティ」を開きます。
「ビルド」のタブから「XML ドキュメントファイル」にチェックを入れます。
この時、テキストボックスの値には、先ほどの「Startup.cs」内の XML ファイル名と一致する値であることを確認します。

f:id:miso_soup3:20141217232513p:plain

Startup.cs にて:

f:id:miso_soup3:20141217232520p:plain

実行

コードの用意は以上です。F5 で実行してみます。実行すると次のようにウィンドウが立ち上がりますので、そのまま閉じないでください。

f:id:miso_soup3:20141217232559p:plain

ブラウザを立ち上げて「http://localhost:9000/swagger」にアクセスすると、Swagger UI のドキュメントページが表示されます。

f:id:miso_soup3:20141217232622p:plain

右上の方に XML ドキュメントコメントが表示されていることが確認できます。
Json ファイルを確認したい場合は、「http://localhost:9000/swagger/api-docs」にアクセスします。Json ファイルがダウンロードできるはずです。
また、各リソースの Json ファイル、例えば User の Json ファイルは「http://localhost:9000/swagger/api-docs//Users」で取得できます。(スラッシュが 2 回続くことに注意。)

(ちなみにこの Json ファイルを利用して API 管理サービス(例:Microsoft Azure の API Management)へ API をインポートすることができます。)

ドキュメントと API のサーバーを別にする場合

Json ファイルの提供元(Web API の提供元)のドメインと、Swagger UI をホストするドメインは別にすることができます。
その場合は、Json ファイルの提供元が CORS に対応している必要があります。
つまり、「Swagger のデモサイト」の上部にあるテキストボックスに、自分の Web API の Json ファイルのアドレスを入力した場合でも、ドキュメントページを表示させることができます。

最後に

まとめ

ASP.NET Web API でも Swagger を使えば、

  • IIS に依存しないドキュメントサイトのホスト
  • Swagger フレームワークのツールの活用

が可能になります。

ただ、Swashbuckle の場合は、Swagger UI が埋め込まれているので、HTML をカスタマイズするには別の方法を採る必要があります。

ASP.NET Web API のドキュメント機能の本質

「ASP.NET Web API のドキュメント機能 = NuGet Package のMicrosoft.AspNet.WebApi.HelpPage 」ではありません。
ASP.NET Web API のドキュメント機能の本質は、「System.Web.Http.Description 名前空間」にあります。

この名前空間にあるオブジェクトは、ASP.NET Web API のAPI の説明用の抽象レイヤーになります。
重要なオブジェクトは、IApiExplorer と ApiDescription です。ApiDescription には 1つの API の情報―HTTP メソッドは何か、パラメーターは何か、といった情報が格納されます。
これらを弄れば、自分用のドキュメントやクライアントコード、テストコードを生成することができます。この IApiExplorer をごりごりする方法は Yao’s blog にたくさんの Tips があります。(1年前から更新が途絶えてるんだけど…;_; )

var config = new HttpConfiguration();
IApiExplorer apiExplorer = config.Services.GetApiExplorer();

この記事で登場したドキュメント生成―NuGet Package の Microsoft.AspNet.WebApi.HelpPage と、Swashbuckle は、この IApiExplorer を利用しています。