Web上で閲覧できるAPIドキュメントをMDwikiとS3を使ってサーバーレスで作る

# Web上で閲覧できるAPIドキュメントをMDwikiとS3を使ってサーバーレスで作る

## やりたい事

APIの数も少数で、リクエストパラメタなどもかなり単純なAPIのドキュメントを作らないといけず

 - できればWordやExcelで作りたくないなぁ
 - でも、ApiBlueprintやSwaggerみたいに自動生成する環境をがっちり作るほどでもないなぁ

という中途半端な事をぼんやり考えていた時、ちょうど良さそうなものを発見しました。

 - [MDwiki：Markdownベースの超シンプルCMS - catch.jp-wiki](http://www.catch.jp/wiki/?MDwiki)

これと、S3を使ってオレオレフォーマットのMarkdown書いて簡単にAPIドキュメントを公開できる環境を作れそうだったので試してみました。


## S3バケットを用意して、Http経由でアクセスできるように設定する

AWSへログインして、S3のメニューから設定します。

#### バケットを作成

で新しくバケットを作ります。例えば「sample-api-document」とかにします。


#### ウェブサイトのホスティングを有効にする

そのバケットの中に入って、右上の方にある「プロパティ」を選び、

 - 静的ウェブサイトホスティング

を選択して、「ウェブサイトのホスティングを有効にする」を選びます。

さらに「インデックスドキュメント」を**「mdwiki.html」**にして保存します。

※mdwiki.htmlはあとで用意します

この時、画面上に「エンドポイント: sample-api-document.s3-website-ap-northeast-1.amazonaws.com」が表示されていると思いますが、このURL

```
http://sample-api-document.s3-website-ap-northeast-1.amazonaws.com/#!index.md
```

でブラウザから接続できるようになります。

#### IPでのアクセス制限を設定する

 - アクセス許可

から「バケットポリシーの編集」を選び、


```
{
    "Version": "2012-10-17",
    "Id": "S3PolicyId1",
    "Statement": [
        {
            "Sid": "IPAllow",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::sample-api-document/*",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": [
                        "xxx.xxx.xxx/32",
                        "yyy.yyy.yyy/32",
                        "zzz.zzz.zzz/32"
                    ]
                }
            }
        }
    ]
}
```

というふうに設定します。公開したいIPをxxx.xxx.xxxの所で複数指定してください。

 - [バケットポリシーの例 - Amazon Simple Storage Service](http://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/example-bucket-policies.html)

また、全世界に向けて公開したい場合は、

```
        {
            "Sid": "IPAllow",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::sample-api-document/*"
        }
```

という感じでConditionのキーごと消してしまえばOKです。

## mdwiki-x.x.x.zipをダウンロードしてS3に配置する

 - [Releases · Dynalon/mdwiki · GitHub](https://github.com/Dynalon/mdwiki/releases)

の「Downloads」の「mdwiki-0.6.2.zip」からダウンロードしてください。（2017-01-25時点）

で、展開してください。中にある**「mdwiki.html」**を、↑で作ったS3に配置します。

## API仕様を書いたドキュメントを用意してS3に配置する

若干面倒なのですが、自分なりに以下のようなフォーマットにしてみました。

```
API名
------------------------

API説明

**URL**

GET /hogehoge/{hoge_id}?hoge_type=xxxx

\```
// sample
https://example.com/hogehoge/{hoge_id}?hoge_type=xxxx
\```

**Parameter**

|     type    |    name   |    key    |  type  | require | detail |
|-------------|-----------|-----------|--------|---------|--------|
| URL         | hoge_id   | -         | string |       1 |        |
| QueryString | hoge_type | hoge_type | string |       0 |        |

**Response**

|        key         |   type  | in case of null | detail |
|--------------------|---------|-----------------|--------|
| header             | object  | not null        | --     |
| header.status_code | integer | not null        | --     |
| header.message     | string  | not null        | --     |
| body.id            | string  | not null        | --     |
| body.name          | string  | null            | --     |
| related            | object  | 空オブジェクト  | --     |
| related.id         | string  | not null        | --     |
| related.name       | string  | null            | --     |
| related.words      | array   | 空配列          | --     |
| related.words[0]   | string  | not null        | --     |


*Response sample*

\```json
{
    "header": {
        "status_code": 0,
        "message": "Success"
    },
    "body": {
        "id": "xxxx",
        "name": "yyyy",
        "related": {
            "id": "xxxx",
            "name": "yyyy",
            "words": [
                "aaa",
                "bbb",
                "ccc"
            ]
        }
    }
}
\```
```

で、作れたらこれを**「index.md」**として適当なところに保存し、

↑↑で作ったS3バケット（mdwiki.htmlと同じ場所）に配置します。


## アクセスしてみる

http://sample-api-document.s3-website-ap-northeast-1.amazonaws.com

に接続すると、表示されると思います。


## まとめ

かなりお手軽に、サーバーレスなAPIドキュメント公開環境を作る事ができました。S3のバージョニングの設定を有効にすることで、世代管理もできるので便利かと思います。ただ、APIの要件が複雑化してきたり、もう少し正式なものが求められる場合は、API blueprintやSwaggerなどのツールを利用し、アプリケーションの実態とAPIの仕様が分離しないような環境を作る必要があるとは思います。

 - [API Blueprint | API Blueprint](https://apiblueprint.org/)
 - [Swagger – The World's Most Popular Framework for APIs.](http://swagger.io/)
 - [Apiary | Platform for API Design, Development & Documentation](https://apiary.io/)