Help us understand the problem. What is going on with this article?

HTMLでWeb APIをつくる

More than 5 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を現在試作しています。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした