Rails での JSON API 実装まとめ

前後リンク

Ruby on JSON

API Technologies

の図のような流れになるんですが、それぞれ見ていきます。

to_json (2011-2013 頃)

2011-2013 年頃、僕らは render :json を使っていました。

render json: @user
render json: @user.to_json

として User#as_jsonUser#to_json を利用します。

この頃はまだ SPA という言葉もなく、ネイティブアプリもそこまで流行っていなかったので これで十分だったのですが、どんどん API に世の中が寄っていき、限界を迎えます。

この頃のツラみ

JSON Template engines (2013-2015 頃)

JSON を組み立てる方法として、RABL や jbuilder といった JSON 用のテンプレートエンジンを使う方法が出てきます。

RABL : 2011年からある老舗の gem。独特の言語で記述する必要があるので学習コストが高め。

jbuilder : rails4 から標準になった。割と簡単に柔軟に書ける。

どちらも「JSON は view」という考え方で、 controller では普通に model を assign して、view で JSON を render する。

この頃のツラみと解決

ActiveModelSerializers (2014-)

jbuilder は部分テンプレートのレンダリングが異常に遅く、 例えばユーザデータ 200 件を含む JSON を返したいだけで 50ms 以上食われることがザラにあった。

このため、遅いところでは「インラインに展開する」とか「to_json を使う」とかを頻繁に行っていて、 これを解決するために serializer 層が生まれた。

AMoS はその流れで出てきたライブラリで、

という serializer としてのメリットと、

という利点、あと何より速さで使われ出した。

render json: @user
class UserSerializer < ActiveModel::Serializer
  attributes :id,
             :name,
             :birthday

  def birthday
    object.created_at.strftime("%Y/%m/%d")
  end
end

この頃のツラみと解決

Grape (2012-2014 頃)

この流れとは別に、Grape が存在しました。 REST API を作成するためのマイクロフレームワークです。

class UserEntity < Grape::Entity
  expose :id
  expose :name
  expose :birthday
end
class API < Grape::API
  format :json
  resources :users do
    get ":id" do
      present User.find(params.id), with: UserEntity
    end
  end
end

grape の記法を学ばなければならず、学習コストは高い。 DSL だけあって、API 定義 (Entity) と router は割と読みやすいので慣れれば楽かも。

この頃のツラみと解決

AMoS と同じように問題を解決しているんだけど、 いかんせん独自フレームワーク、独自 DSL だったのがネックですね。 Rails じゃないと使われないという悲しみがあるのでした。

JSON Schema (2014-2016 頃)

JSON Schema とは: JSON で表現されるデータに対してデータ定義する Schema を記述する仕組み。

超簡単な例だと以下のようなデータと schema 定義。(概念コードです

{
  "id": 12345678,
  "name": "Taro",
  "birthday": "2000-01-01 00:00:00"
}
properties:
  id:
    type: integer
  name:
    type: string
  birthday:
    type: date-time

この頃のツラみと解決

また、他に

といった辺りも大きなメリットです。

先駆者たち

DeNA、Cookpad 等。2014年の中頃辺りから盛り上がってきた。

API Description Language (2016-)

JSON Schema は基盤となり、JSON Schema の上で API を記述する言語が生まれてきます。

JSON Schema は「JSON の構造を定義できる」だけで、API として使う JSON」の定義は JSON Schema の上にもう一つレイヤーが必要。

そこで出てきたのが以下の諸々で、現在 5 派閥ぐらいありそうです。

だいたい全て

みたいな機能を備えてます。

この頃のツラみと解決

当時ツラかった内容が全て解決していますね。

参考URL

API Query Language (2016-)

GraphQL が爆誕します。

GraphQL は今までの流れでも解決できていない、「そもそも REST は本質的に難しくて 徹底できない。RESTish が限界」ということを認めて、別のアプローチを取ります。

もちろんデメリットもあります。

詳しくは第 4 部 The NEXT of REST で。

前後リンク