RailsはデフォルトでJSONがView
Railsをつかっていると、デフォルトでjbuilderというgemが含まれていて、JSONを返すレスポンをさばくとき、JSONは viewとして扱うようになっています。
jbuilderを使っていれば、処理は同じでレスポンスのフォーマットだけが違う。みたいなアクションを作りたいとき、すごくすっきり書けます。
class ProductsController < ApplicationController
def show
@product = Product.find(params[:id)
end
end
上のように書いておけば、リクエストのフォーマットに応じてHTMLテンプレファイルかJSONのDSLファイルか適切なものを探してそれをレンダリングして返してくれます。
HTMLとJSONが単にフォーマットが違うだけ。という扱いがされているからです。両者の実装上のちがいは、置くファイルのフォーマットだけになります。
HTMLはUI、JSONはデータ
HTMLもJSONも、ただ Content-Typeが違うだけ。なのはたしかです。しかし私見ですが、HTMLとJSONはもはや表現している内容の幅に開きがありすぎるので、統一的に扱うべきなのか疑問です。
通常、2つのフォーマットは以下のようなことを表現しています。
- HTML → プレゼンテーションやUIを表現したもの
- JSON → データを表現したもの
JSONがコントローラで選択されるViewということになっていると、たとえ同じリソースを表現しているJSONだったとしても、URLが違ったり、別のリソースにネストしていたり、文脈に応じてフォーマットが変わることを許してしまいます。
この柔軟性は必要悪です。JSONを受けとるクライアントにとってみれば、理想的には1つのリソースのJSON表現は1つであったほうが扱いやすいからです。
使う場所によってプロパティが変わってしまい、いつどのように変わるかはドキュメントを見ないとわからない。なんていうクラスがあったら見通しが悪いと思いますが、JSONにも同じようなことが言えるとおもわれます。
HTMLはUIを含んでいる
HTMLは、人間に対してデータをプレゼンテーションしていて、見た目に関する情報や、関連するjsやcssの情報なんかを含んでいます。しかも、URLによって表示項目が変わったりするのは普通です。
たとえば、
<span>Yamada</span>
という表現がされていたユーザというリソースが、別の画面では
<span><div class="suteki">Yamada!!!</div></span>
みたいに表現が変わるのはごく普通のことです。
過去の思想がそうだったかはわからないですが、現在のHTMLは、人間になにをどう見せるかを記述するためのものとなっているので、URLごと、アクションごとに別のものがレンダリングできる柔軟性を獲得しまくっていくのは自然なことです。
JSONはどうでしょう。JSONは、基本的にはプログラムが読むためのものです。
{"name": "Yamada"}
というJSONが、別のURLでは
{"name": { "suteki": "Yamada!!!"} }
みたいになってたら、ちょっと極端な例ですが、とても使えたもんじゃないですよね。
そもそも、Viewとデータを分離しているのは、データそのものと、見た目の表現の形式を分離したいからです。JSONでデータをうけとり、そこからさらにネイティブアプリなりHTMLなりで見た目の表現を組み立てるクライアントの視点からみるとJSONはViewではないと言うことができます。
gemたち
以上のような理由から、僕は、モデルのデータから一意なJSONを組み立てるタイプの gem を好んで使っています。
そのようなノリのあるgemには以下のようなものがあります。