Edited at

HTMLでWeb APIをつくる

More than 3 years have passed since last update.

シングルページアプリケーションやモバイルアプリなどの普及により、サーバサイドではJSONを出力するWeb APIの必要性が高くなってきています。みなさんはどのようにWeb APIを作っているでしょうか。


JSONはビュー

http://qiita.com/yuch_i/items/f6b04e2875f432f8f806


RailsでJSON APIを定義する時、素のままでやろうとすると

コントーラでto_jsonを呼んだり、モデルにas_jsonを定義したりすることになるかと思います。

モデルに書くとAPIによって出力内容を変えたい場合にとても苦労します。

API数が増えれば増えるほどモデルが複雑になっていきます。

APIレスポンスとしてのJSONはコントローラやモデルに書くべきでしょうか?

ビューに書いた方が自然ではないでしょうか?


これはRailsでの話ですが、Railsに限らず、フレームワークを使ってWeb APIを作るときに一般的にあてはまることだと思います。


変化に強い、再利用可能なAPIが必要

モデルをただJSONに変換すると、内部仕様であるモデルの属性名がそのまま露出します。意味はほとんど同じなのに、少しだけ違うAPIができてしまいます。さらに、属性名に依存してクライアントを作ってしまうと、モデルが変更されたときに壊れます。

今のWeb APIはそれぞれバラバラなフォーマットで定義されていて、共通な部分が少なすぎるという印象があります。APIが変わると、いつもゼロからコーディングしなければなりません。

では具体的にどうやって書けばいいでしょう?


リンクは柔軟性を生む

リンクは、あるリソースを別のリソースと結びつけるものです。これにより、Web APIに柔軟性が生まれます。

クライアントを壊さずにAPIを変更するには、モデルの属性名を「変更されないもの=標準の名前」に結びつければいいのです。

さらに、標準の名前に結びつけることで、少しずつ違うAPIが標準化され、再利用することができます。


HTMLをテンプレートとして使う

JSONには、残念ながらリンクがありません。

しかし、リンクを持っていて、さらに標準の名前に結びつけるしくみも持っているフォーマットがあります。HTMLです。

そのしくみの1つとして、microdataがあります。

https://support.google.com/webmasters/answer/176035?hl=ja

<div itemscope itemtype="http://schema.org/Person">

私の名前は<span itemprop="name">東京太郎</span>ですが、
みんなから「<span itemprop="nickname">東太</span>」と呼ばれています。
私のホームページは、
<a href="http://www.example.com" itemprop="url" rel="about">www.example.com</a> です。
<span itemprop="address" itemscope
itemtype="http://schema.org/Address">
<span itemprop="locality">東京都</span>,
<span itemprop="region">港区</span>
</span>
に住んでおり、<span itemprop="title">エンジニア</span>
として <span itemprop="affiliation">ACME 社</span>に勤めています。
</div>

このマークアップで「schema.org」という標準の名前と結びつけることにより、GoogleはこのHTMLをクロールしたときデータとして認識し、検索結果に反映させます。

このHTMLは例えば、このようなJSONとみなすことができます。(これはHALというフォーマットのJSONです)

{

"name":"東京太郎",
"nickname":"東太",
"url":"http://www.example.com",
"title":"エンジニア",
"affiliation":"ACME 社",
"_links":{
"type":{
"href":"http://schema.org/Person"
},
"about":{
"href":"http://www.example.com"
}
},
"_embedded":{
"address":[
{
"locality":"東京都",
"region":"港区",
"_links":{
"type":{
"href":"http://schema.org/Address"
}
}
}
]
}
}

このような形になると、もうWeb APIそのものです。つまり、HTMLはWeb APIとして使えるのです。元のモデルやHTMLが変更されても、microdataのマークアップさえ正しければ、同じJSONとみなすことができます。クライアントは壊れません。

JSONへの変換(もしくはデータの抽出)はサーバサイドでもクライアントサイドでも構いません。

クライアントサイドではmicrodata DOM APIという仕様が定義されていて、JavaScriptによる実装も存在します。

microdata→JSON変換というアイデアは、以前から存在していて、新しいというわけではありません。

その他のJSON変換仕様の例:

俺俺フォーマットのJSONが濫造される中、なんとか簡単に統一的なフォーマットのJSONを作る方法はないか、と考えた結果、これにたどりつきました。

これからAPIを作るときには、HTMLを書くというのはどうでしょうか?


試作中

このアイデアが実現できるように、Railsで自動的に変換してJSON(HAL, UBER)レスポンスを返すgemを現在試作しています。