API BlueprintでWebAPI仕様書を書く

WebAPIを開発する場合、APIの利用者向けにAPI仕様書を書くと思います。 API BlueprintというWebAPI仕様書のためのMarkdown記法を拡張した記法があり、これに則って仕様書を書くとスムーズに書くことができます。 今回は、このAPI Blueprintに則ってWebAPI仕様書を書く際のちょっとしたTipsを書いてみます。

前提

ここでは、

  • API Blueprint形式のドキュメントをテキストエディタで書く。
  • ドキュメントは、aglioを使ってHTML化する。

を前提としています。

API Blueprint

API Blueprintは、公式サイトに、

A powerful high-level API description language for web APIs.

とあるように、API仕様書を書くための記法です。

API Blueprintの記法の詳細については、ここでは扱いませんが、例を載せておきます。

FORMAT: 1A
HOST: https://www.example.com

# API

API仕様書のサンプルです。

# Group Articles
## Articles [/v1/articles]
### GET

記事リストを取得する。

+ Request

    + Headers

            Content-Type: application/json

+ Response 200 (application/json)

    + Attributes (ArticleList)

### POST

記事を登録する。

+ Request

    + Headers

            Content-Type: application/json

    + Attributes (ArticleCreateParams)

+ Response 201 (application/json)

    + Attributes (Article)

# Group Comments
## Comments [/v1/articles/{article_id}/comments]
### GET

記事に対するコメントリストを取得する。

+ Parameters

    + article_id: 1 (number) - 記事ID

+ Request

    + Headers

            Content-Type: application/json

+ Response 200 (application/json)

    + Attributes (CommentList)

aglio

API Blueprint形式のドキュメントを作った後、「aglio」というツールを使ってHTML化することができます。 上述のAPI Blueprint形式のドキュメントをaglioでHTML化すると、↓のようなHTMLが得られます。

Tips

ここからは、API Blueprint形式で仕様書を書くにあたり、こう書くと書きやすい、といったTips的なことをいくつか纏めてみます。(もちろん、すべての人にとって必ずしも書きやすい方法ではないと思います。)

Overviewを書く

複数のAPIを定義する場合に、各APIで共通の仕様(HTTPヘッダ)を説明するのには、Overviewに書くと良さそうです。Overviewは、「API name and overview section」という、ドキュメントの先頭のセクションに書くことができます。

ファイルを分割する

定義するAPIの数が多い場合、単一のファイルのすべてを書くと、全体の見通しが悪くなり、得策とは言えません。 aglioを使ってHTML化する場合、

<!-- include(partial.md) -->
<!-- include(partial.apib) -->

のように、外部ファイルをインクルードして、結合することができます。 例えば、ブログのようなシステムでのAPIを定義する場合に、認証API、ユーザAPI、記事API、コメントAPIなどが定義できそうですが、このような場合は、それぞれの仕様を別々のMarkdownファイルに書き、本体のファイルで、

<!-- includes(auth.md) -->
<!-- include(users.md) -->
<!-- include(articles.md) -->
<!-- include(comments.md) -->

とすると、管理がしやすくなります。

Attributesセクションを使う

RequestセクションやResponseセクション配下のBodyセクションにJSONのデータ構造を一つ一つ書くのはとても面倒です。 Data Structuresにデータ構造を定義しておくと、Attributesセクションにデータ構造名を書くだけで、簡単にJSONのフォーマットを表現できるようになります。

例えば、

# Data Structures
## UserCredentials
+ email: `foo@bar.com` (string) - Email Adress
+ password: `secret` (string) -Password

のようにData Structuresを定義しておくと、

Request (application/json)

    + Attributes (UserCredentials)

と書くことができます。

Data Structuresは細かい粒度で定義する

1つのリソースに対して、

  • データ取得時のレスポンスに乗せるJSON
  • データ登録時のリクエストに乗せるJSON
  • データ更新時のリクエストに乗せるJSON

で、それぞれ微妙に属性が異なる場合があると思います。 例えば、データ取得時は生成日時、更新日時を乗せるが、データ登録時は受け取る必要がない、などです。

この場合、次のようにData Structuresに別々のデータ構造として定義してしまえば、話が簡単になります。

# DataStructures
## Article
+ id: 1 (number) - ID
+ title: `Awesome Article` (string) - title
+ body: `This is a body.` (string) - body
+ status: 0 (enum[number]) - status
+ created_at: `yyyy-MM-ddThh:mm:ss.SSSZ` (string) - when created
+ updated_at: `yyyy-MM-ddThh:mm:ss.SSSZ` (string) - when updated

## ArticleCreateParams
+ title: `Awesome Article` (string) - title
+ body: `This is a body.` (string) - body

## ArticleUpdateParams
+ id: 1 (number) - ID
+ title: `Awesome Article` (string) - title
+ body: `This is a body.` (string) - body
+ status: 0 (enum[number]) - status

DataStructuresにはネストした構造が定義できることを知る

僕は当初気づかなかったのですが、Data Structuresに定義するデータ構造はネスト構造が定義できます。 例えば、ArticleとCommentが1対多の関係にあって、ArticleのJSONの中にCommentリストを含めたデータ構造を定義することができます。

## Article (object)
+ id: 1 (number) - ID
+ title: `xxxxxxxxxx` (string) - Title
+ body: `xxxxxxxxxx` (string) - Body
+ created_at: `2017-02-01T12:34:56.000Z` (string) - When created
+ updated_at: `2017-02-01T12:34:56.000Z` (string) - When updated
+ comments (array)
  + (Comment)

## Comment (object)
+ id: 1 (number) - ID
+ article_id: 1 (number) - Article ID
+ body: `xxxxxxxxxx` (string) - Body
+ created_at: `2017-02-01T12:34:56.000Z` (string) - When created
+ updated_at: `2017-02-01T12:34:56.000Z` (string) - When updated

と定義すると、

[
  {
    "id": 1,
    "title": "xxxxxxxxxx",
    "body": "xxxxxxxxxx",
    "created_at": "2017-02-01T12:34:56.000Z",
    "updated_at": "2017-02-01T12:34:56.000Z",
    "comments": [
      {
        "id": 1,
        "article_id": 1,
        "body": "xxxxxxxxxx",
        "created_at": "2017-02-01T12:34:56.000Z",
        "updated_at": "2017-02-01T12:34:56.000Z"
      }
    ]
  }
]

というJSONとして表現されます。


以上、API BlueprintでWebAPI仕様書を書く際のTipsを纏めてみました。