概要
WebAPIの仕様を記述するための言語であるAPI Blueprintと、API Blueprintで記述されたAPPI仕様からドキュメントとなるHTMLを生成したり、Webサーバとして動作することでドキュメントサーバを構築できるaglioを用いて、Debian上にAPIドキュメントサーバを構築してみたのでその備忘録。
API Blueprint + aglio で作成できるAPIドキュメントのサンプルはこちら
前提
node/npmが使えて、Webブラウザが使える環境からアクセスできるDebianがあること
debian | 9.3 |
node | 9.8.0 |
npm | 5.6.0 |
aglio | 2.3.0 |
API Blueprint/aglioについて
API Blueprintは、WebAPIの仕様を記述するための言語。
例えば以下は、API BlueprintのHello World!
# GET /message + Response 200 (text/plain) Hello World!
上記コードは、「/messagに対してGETリクエストを送信すると、ステータスコードが200で、text/plain形式の”Hello World!”が返却される」というAPIの仕様を表現している。
上記のHello,Worldだけだとイマイチしっくり来ないが、API Blueprintには様々な構文が用意されている。
その辺りはドキュメントが豊富なので、Exampleに目を通してみるとイメージが付くかもしれない。API Blueprintを使用することで、表現力豊かなAPI仕様を書くことができ、素早い設計やプロトタイプの構築を行えるようになる。
また、関連ツールを用いることで、ドキュメントサーバを構築したり(本記事)、APIの自動テストを生成したり、APIのモックを用意できたり、はては実コードの生成まで行うことができる。
aglioはそんな関連ツールの一種で、API Blueprintで書かれた仕様を元にHTMLを生成したりWebサーバを立ち上げることで、APIドキュメントサーバを構築することができる。以降では、aglioのインストールから、API Blueprintによる仕様からのドキュメント生成、ドキュメントサーバの起動までを行う。
aglioのインストール
npmでaglioをインストール。aglioコマンドを使えるようにしたいので、gオプションでグローバルインストール
$ npm install -g aglio
以下のようなエラーが出る場合
{ Error: Could not get CSS: Error writing cached CSS to file: ENOENT: no such file or directory, open '/usr/local/lib/node_modules/aglio/node_modules/aglio-theme-olio/cache/bb851236ef33e467631256487d5bbe519de24415.css' at Object.fs.openSync (fs.js:667:18) at Object.fs.writeFileSync (fs.js:1326:33) at /usr/local/lib/node_modules/aglio/node_modules/aglio-theme-olio/lib/main.js:222:14 at /usr/local/lib/node_modules/aglio/node_modules/less/lib/less/render.js:35:17 at /usr/local/lib/node_modules/aglio/node_modules/less/lib/less/parse.js:63:17 at ImportVisitor.finish [as _finish] (/usr/local/lib/node_modules/aglio/node_modules/less/lib/less/parser/parser.js:183:28) at ImportVisitor._onSequencerEmpty (/usr/local/lib/node_modules/aglio/node_modules/less/lib/less/visitors/import-visitor.js:35:14) at ImportSequencer.tryRun (/usr/local/lib/node_modules/aglio/node_modules/less/lib/less/visitors/import-sequencer.js:50:14) at /usr/local/lib/node_modules/aglio/node_modules/less/lib/less/visitors/import-sequencer.js:19:25 at fileParsedFunc (/usr/local/lib/node_modules/aglio/node_modules/less/lib/less/import-manager.js:50:17) errno: -2, code: 'ENOENT', syscall: 'open', path: '/usr/local/lib/node_modules/aglio/node_modules/aglio-theme-olio/cache/bb851236ef33e467631256487d5bbe519de24415.css' }
存在しないらしいディレクトリを作ってあげる(パスは環境によって異なるのでエラーメッセージなどで確認する)
$ cd /usr/local/lib/node_modules/aglio/node_modules/aglio-theme-olio $ mkdir cache
その後再度インストールで解決。
aglioコマンドが使えるようになっていればOK
$ aglio -v aglio 2.3.0 olio 1.6.3
ドキュメントの作成
適当なディレクトリで、input.mdを作成する。内容は最初に掲示したHello,Worldと同様
# GET /message + Response 200 (text/plain) Hello World!
aglioコマンドで、API Blueprintで記述したMarkdownファイルからHTMLファイルを生成する。oオプションで出力を指定できるので、output.htmlにしておく。
$ aglio -i input.md -o output.html
出力されたoutput.htmlをブラウザで開くと、以下のようにドキュメントが生成されていることがわかる。
さらに、以下のようなやや複雑なAPI Blueprintコードでinput.mdを上書きして、再度aglioコマンドでoutput.htmlを出力すると
FORMAT: 1A # Requests API Following the [Responses](05.%20Responses.md) example, this API will show you how to define multiple requests and what data these requests can bear. Let's demonstrate multiple requests on a trivial example of content negotiation. # Group Messages Group of all messages-related resources. ## My Message [/message] ### Retrieve a Message [GET] In API Blueprint, _requests_ can hold exactly the same kind of information and can be described using exactly the same structure as _responses_, only with different signature – using the `Request` keyword. The string that follows after the `Request` keyword is a request identifier. Again, using explanatory and simple naming is the best way to go. + Request Plain Text Message + Headers Accept: text/plain + Response 200 (text/plain) + Headers X-My-Message-Header: 42 + Body Hello World! + Request JSON Message + Headers Accept: application/json + Response 200 (application/json) + Headers X-My-Message-Header: 42 + Body { "message": "Hello World!" } ### Update a Message [PUT] + Request Update Plain Text Message (text/plain) All your base are belong to us. + Request Update JSON Message (application/json) { "message": "All your base are belong to us." } + Response 204
以下のように柔軟にAPIの仕様を記述、ドキュメントの構築を行うことができる。
ドキュメントサーバの起動
前述の方法だと、作成中は毎回コマンドを叩いてHTMLを生成して、ブラウザを再読込してとひと手間かかるし、ドキュメントを公開するのも面倒だ。
そこで、aglioのWebサーバ機能を用いて、ドキュメントサーバを立ち上げる。aglioでWebサーバを立ち上げることで、以下の恩恵を受けられる
- aglioが動いているホスト/ポートに対してHTTPでリクエストすることで、HTML化されたドキュメントを取得することができる
- Webサーバが立ち上がっている状態で、API Blueprintのコードを編集すると、即座に再ビルドがかかり常に最新の状態になる
- 再ビルドがかかった際にブラウザでドキュメントを表示していると、ブラウザも自動で再読込がかかる
以下のコマンドでローカルホストの80番ポートにWebサーバを立ち上げることができる
$ aglio -i input.md -s -p 80 -h '0.0.0.0' Server started on http://0.0.0.0:80/ Rendering input.md Socket connected
Webサーバが立ち上がり、ブラウザでアクセスしている状態で、エディタでコードを変更すると、以下のようにリアルタイムに再ビルド、ブラウザ更新が行われる。
興味が湧いた人へ
本記事では、API Blueprintとaglioでこんなことが出来るよと触り程度紹介したので、実際に使って見るには情報が不足している。
興味が湧いた人は以下のリンクからさらに調べてみると、より丁寧に書かれているので、さらに理解が深まるはず。