APIドキュメント標準化 現状確認

こんにちは、エキサイト恋愛結婚担当エンジニアの松下です。
今回は先日社内で開催されたLTで私が発表した内容について触れたいと思います。
LTの様子は以前の記事をどうぞ。

めんどくさい人はこちらのスライドをどうぞ。

はじめに

みなさんはAPI仕様を書くときどうしてますか?
Markdownで書いてGithubのreadmeに含めたり、confluenceやesa.io等情報共有ツールがあればそこに書いたり…

項目としてよくあるのは以下のようなものでしょうか。

  • HTTPメソッド(GET/POST/PUT/DELETE...)
  • エンドポイント
  • リクエストパラメータ
  • レスポンス
  • サンプル

パラメータの説明なんかはMarkdownならテーブル記法で書いたりする人も多いんじゃないかと思います。
いずれにせよどんな項目をどのように書くかは書き手によってバラバラです。
そしてAPI仕様書の「理解しやすさ」は書き手に左右されます。

そもそも「構造」と「注釈」の混在するAPI仕様を日本語や英語といった言語のみで記述するにはあまりにも制約が無さすぎるのです。


もし世界中のAPI仕様書が同じようなフォーマットで記述されていたとしたらハッピーですよね。

現在、APIを記述するための言語やドキュメントを統一しようという動きが起きています。

APIドキュメント生成ツールで有名ドコロは以下のようなものがあります。



これらの特徴や触ってみた感想について書いていきます。

記法例について

以降の解説で記述している各APIドキュメント生成ツールによる記法例は以下のものを想定しています。

シチュエーション:ブログ記事詳細取得API

HTTPメソッド エンドポイント リクエストパラメータ リクエストヘッダ
GET /v1/article/{article_id} article_id(必須) Content-Type: application/json
Accept: application/json

レスポンス(200)

ヘッダ:Content-Type: application/json

ボディ:

 {
"data": {
"id": 3,
"title": "記事タイトル",
"body": "<html>HTML本文</html>",
"created_at": "2016-05-22T14:56:29.000Z",
"updated_at": "2016-05-22T14:56:28.000Z",
"author": "author1",
"tags": [
{"id": 1, "tag_name": "タグ名1"},
{"id": 2, "tag_name": "タグ名2"}
]
}
}

補足:

authorは1記事に対して一人のみ、tagsは1記事に対して複数タグが配列で返却される。

tagsが空の場合もある。


API Blueprint

公式サイト
Makdownを拡張した記法で記述します。
JSONスキーマも裏でよしなに作ってくれます。

記法例

 FORMAT: 1A
HOST: https://sampleblog.com

# API Blueprintサンプル

ブログAPI。

## 記事単体 [/v1/article/{article_id}]

### 記事詳細取得API [GET]

記事詳細を取得する。記事個別ページで使用し、記事毎のauthor,tag情報も返却する

+ Request (application/json)

+ Headers

Accept: application/json

+ Parameters

+ article_id: 3 (number, required)

+ Response 200 (application/json)

+ Attributes
+ data (required)
+ id: 3 (number, required)
+ title: 記事タイトル (string, required)
+ body: `<html>HTML本文</html>`(string, required)
+ created_at: `2016-05-22T14:56:29.000Z` (string, required)
+ updated_at: `2016-05-22T14:56:28.000Z` (string, required)
+ author: author1 (string, required) -- 記事毎に一人のユーザ(著者)
+ tags (array) -- 記事毎に複数のタグ
+ (object)
+ id: 1 (number, required)
+ tag_name: タグ1 (string, required)
+ (object)
+ id: 2 (number, required)
+ tag_name: タグ2 (string, required)


関連ツール

APIドキュメント作成サービスです。

API Blueprintで書かれた仕様からドキュメントを生成したり、モックサーバを立ててくれたりします。Betaですが後述するSwaggerにも対応してます。

以下の様なモックをすぐ作れるので便利です。

https://private-e0af0-blogsample.apiary-mock.com/v1/article/3


aglio

API Blueprint形式で書かれた仕様からHTMLドキュメントを生成してくれます。

テーマがいくつか用意されており、カスタマイズもできます。

Live Reload機能が有効なローカルサーバをたてられます。


その他

https://apiblueprint.org/tools.html


RAML

公式サイト

YAMLを拡張した記法で記述します。

共通部分を抜き出して再利用したり、他のファイルからincludeしたりといった、プログラミング言語っぽいことができます。


記法例

sampleblog.raml
#%RAML 0.8
---
baseUri: https://mocksvc.mulesoft.com/mocks/63e6c366-34a6-4693-b078-ae3e425848d8
title: RAML サンプル
version: v1
mediaType: application/json

schemas:
- article: !include sampleblog-include-article.schema

resourceTypes:
- collection-item:
description: Entity representing a <<resourcePathName|!singularize>>
get:
responses:
200:
body:
application/json:
schema: <<resourcePathName|!singularize>>
example: |
<<exampleItem>>

/article:
/{article_id}:
uriParameters:
article_id:
description: 記事ID
type: integer
required: true
example: 3
type:
collection-item:
exampleItem: !include sampleblog-include-article-item.sample
description: 記事単体
get:
description: 記事詳細を取得する。記事個別ページで使用し、記事毎のauthor,tag情報も返却する

sampleblog-include-article.schema

{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"id": {
"type": "number"
},
"title": {
"type": "string"
},
"body": {
"type": "string"
},
"created_at": {
"type": "string"
},
"updated_at": {
"type": "string"
},
"author": {
"type": "string",
"description": "- 記事毎に一人のユーザ(著者)"
},
"tags": {
"type": "array",
"description": "- 記事毎に複数のタグ"
}
},
"required": [
"id",
"title",
"body",
"created_at",
"updated_at",
"author"
]
}
},
"required": [
"data"
]
}

sampleblog-include-article-item.sample

{
"data": {
"id": 3,
"title": "記事タイトル",
"body": "<html>HTML本文</html>",
"created_at": "2016-05-22T14:56:29.000Z",
"updated_at": "2016-05-22T14:56:28.000Z",
"author": "author1",
"tags": [
{
"id": 1,
"tag_name": "タグ1"
},
{
"id": 2,
"tag_name": "タグ2"
}
]
}
}


!includeで他のファイルをincludeしたり、resourceTypesでタイプを定義、使い回すことができます。


関連ツール

APIドキュメント作成サービスです。

RAMLで書かれた仕様からドキュメントを生成したり、モックサーバを立ててくれたりします。

以下の様なモックをすぐ作れます。

$ curl -H 'Content-Type:application/json' https://anypoint.mulesoft.com/apiplatform/proxy/https://mocksvc.mulesoft.com/mocks/63e6c366-34a6-4693-b078-ae3e425848d8/article/3

Atomエディタで使えるRAMLのIDEです。(Beta)

f0364156_15360319.png

その他

http://raml.org/projects/projects


Swagger

API言語の中では老舗です。(Initial Commit: July 2011)

API BlueprintやRAMLと同じくAPI仕様を先に書いてから実装していくトップダウンと、実装コードにSwagger Annotationを書き、API仕様を出力させるボトムアップの両方対応できます。

トップダウンの場合定義はJSONかYAMLで記述します。

このファイルをSwagger Specification(Swagger Spec)と呼びます。


記法例

swagger: '2.0'
info:
title: Swagger サンプル
description: ブログAPI
version: "1.0.0"
host: sampleblog.com
schemes:
- https
basePath: /v1
consumes:
- application/json
produces:
- application/json
paths:
/article/{article_id}:
get:
summary: 記事詳細
description: |
記事詳細を取得する。記事個別ページで使用し、記事毎のauthor,tag情報も返却する
parameters:
- name: article_id
in: path
description: 記事ID
required: true
type: number
tags:
- Article
responses:
200:
description: 記事詳細
schema:
$ref: '#/definitions/Article'
definitions:
Article:
type: object
required:
- id
- title
- body
- created_at
- updated_at
- author
- tags
properties:
id:
type: number
description: 記事ID
title:
type: string
description: 記事タイトル
body:
type: string
description: HTML本文
created_at:
type: string
format: datetime
description: 作成日時
updated_at:
type: string
format: datetime
description: 更新日時
author:
type: string
description: 著者
tags:
type: array
items:
$ref: '#/definitions/Tags'
Tags:
type: object
required:
- id
- tag_name
properties:
id:
type: number
description: タグID
tag_name:
type: string
description: タグ名

関連ツール

Swagger SpecからAPIドキュメントを作成するツールです。

ブラウザ上から実際にAPIを叩けたりします。


Swagger Specエディタです。

公式ライブデモ


Swagger Specからクライアントのコードを生成するツールです。

APIサーバのスタブも作れます。


その他

使ってみた感想

API Blueprint

Markdownと言いつつインデントに決まりがあったりと結構癖があります。

書式ミスを指定してくれるエディタが無いとかなりきついです。

が、一つでもエンドポイントを記述すればあとはコピペでなんとかなります。

includeや使い回し等の機能がないので、ファイルを分割する場合はファイルを一つにに結合するスクリプト等が必要になります。

若干動作が重いですがapiaryの万能感があります。


RAML

外部ファイルを取り込む「!include」ぐらいなら良いんですが、下手に継承関係が定義できるせいで凝りすぎると沼に嵌りそうです。

yamlで無茶しすぎなのでは...?

それとRAML0.8と1.0で結構記述が変わるので注意が必要です。

RAMLとは別にjson schemaに慣れてない人はそちらも知っておく必要があるので、言うほど学習コスト低くないです。


Swagger

3つの中で一番多機能な印象です。関連ツールの選択肢が多いので最初はとっつきにくいです。

記法はピュアなYAMLなので素直に書けます。

チーム内でのコラボレーション周りが弱く、Swagger Codegenでサーバモック用のStubを出力してはくれますがそこから先は開発者におまかせです。

apiaryを使うこともできますが現時点ではBetaで若干動作がおかしいところがあります。

apistudio.ioを使えば固定値ですがレスポンスを自動でシミュレーションしてくれます。


将来性

Googleトレンド

リンク
f0364156_17025756.png

Swaggerがすごい勢いで伸びてます。

Open API Initiative

2015年、RESTful APIのインターフェイスを記述するための標準フォーマットを推進する

Open API InitiativeがLinux Foundationの協力の元結成されました。Googleをはじめそうそうたるメンバーが参加してます。

f0364156_17050656.png

そしてOpen API Initiativeが採用しているのがSwaggerです。


まとめ

API言語は今揺籃期です。

長いものに巻かれたい自分としては早く標準化して欲しいところですが、所詮はツールなのでチーム内で使いやすいものを選んで知見をためていくのが今の段階では良いかと思います。

そもそもこんなの要る?って議論はあると思いますが、将来的にもうひとつのAPI標準化(API設計標準化※)が落ち着いた時にこのようなツールは真価を発揮してくれるんじゃないかと思います。

※RESTfulとかHATEOAS(HAL)とかJSON APIとかオレオレベストプラクティスとかその辺のゴタゴタの話です。



エンジニア募集

エキサイトではエンジニアとして一緒に働いてくださる方を新卒採用と中途採用で募集しています。詳しくは、こちらの採用情報ページをご覧ください。

by ex-engineer | 2016-07-19 10:00