RABL (Ruby API Builder Language) は、JSON、XML、MessagePack、PList、BSON を生成するための Rails および Padrino の Ruby テンプレートシステムです。
ActiveRecord の to_json メソッドを使用していると、API 生成のためにより表現力豊かで強力なソリューションが欲しくなります。これは特に、JSON 表現が複雑であったり、データベースで定義された正確なスキーマと一致しない場合に当てはまります。
具体的には、以下のことを簡単に行いたいと考えています。
ActiveRecord の to_json メソッドを使用して JSON レスポンスを生成しようとしたことのある人なら、この制限的なアプローチの苦しみを感じたことでしょう。RABL は、API レスポンス生成にまったく新しい方法でアプローチすることで、これらの問題を解決するために作られた汎用テンプレートシステムです。
RABL の核となるのは、API データ表現をアプリケーションの ビュー レイヤーに委ねることで MVC の原則に従うことです。RABL に関する一般的な誤解については、RABL を理解する ガイドをご覧ください。このプロジェクトに関する混乱を解消するのに役立ちます。
v0.8.0(2013年2月14日リリース)は multi_json 依存関係を削除し、Oj(または JSON)を JSON パーサーとして使用します。コードが簡素化され、依存関係が削除されますが、MultiJson への参照を削除する必要があるかもしれません。
v0.6.14(2012年6月28日リリース)では、テンプレートをテストするために RSpec で render_views を使用する必要があります。そうしないと、コントローラーは ERB テンプレートと同様に render コマンドをそのまま通過させます。
RABL を gem としてインストール:``` gem install rabl
またはGemfileに追加してください:```ruby
# Gemfile
gem 'rabl'
# Also add either `oj` or `yajl-ruby` as the JSON parser
gem 'oj'
依存関係をインストールするために bundle install を実行します。
Rails 2.3.8(以降)、Rails 3.X、または Padrino を使用している場合、RABL は設定なしで動作します。
重要: Padrino を使用する場合、Gemfile 内で rabl gem が padrino gem の後にリストされている ことを確認してください。そうしないと、Rabl がテンプレートエンジンとして正しく登録されません。
Sinatra、または他の tilt ベースのフレームワークでは、単に次のように登録します:```ruby Rabl.register!
and RABL will be initialized and ready for use. For usage with Sinatra, check out
the [Sinatra Usage](https://github.com/nesquena/rabl/wiki/Setup-for-Sinatra) guide.
## Overview ##
You can use RABL to generate JSON and XML based APIs from any ruby object.
With RABL, the data typically is derived primarily from models (ORM-agnostic) and the representation of the API output is described within
a view template using a simple ruby DSL. This allows you to keep your data separated from the JSON or XML you wish to output.
Once you have installed RABL (explained above), you can construct a RABL view template and then render the template
from your Sinatra, Padrino or Rails applications from the controller (or route) very easily. Using [Padrino](http://padrinorb.com) as an
example, assuming you have a `Post` model filled with blog posts, you can render an API representation (both JSON and XML) by creating a route:```ruby
# app/app.rb
get "/posts", :provides => [:json, :xml] do
@user = current_user
@posts = Post.order("id DESC")
render "posts/index"
end
次に、@postsのAPI出力を表現するために、以下のRABLテンプレートを作成できます。```ruby
collection @posts attributes :id, :title, :subject child(:user) { attributes :full_name } node(:read) { |post| post.read_by?(@user) }
`http://localhost:3000/posts.json` にアクセスすると、次のJSONまたはXMLが出力されます。```js
[{ "post" :
{
"id" : 5, title: "...", subject: "...",
"user" : { full_name : "..." },
"read" : true
}
}]
以上が基本的な概要ですが、パーシャル、継承、カスタムノードなど、さらに多くの機能があります。RABLの詳細は以下をお読みください。
RABLは、動作させるためにほとんど設定を必要としないように設計されています。ほとんどのシナリオでその通りですが、必要に応じてアプリケーションで以下のグローバル設定を行いたい場合もあります(このブロックは完全にオプションです):```ruby
require 'rabl' Rabl.configure do |config|
end
各オプションはRABLの出力に関する動作を指定します。`include_json_root` を無効にすると、出力内の各ルートオブジェクトのルートノードが削除され、`enable_json_callback` を有効にすると、受信リクエストに 'callback' パラメータがある場合に 'jsonp' スタイルのコールバック出力がサポートされます。
`include_child_root` を false に設定すると、デフォルトでレスポンス内の子オブジェクトにルートノードが含まれなくなります。これにより、希望するレスポンス構造をさらに微調整できます。
`cache_engine` が設定されている場合、`fetch` メソッドを持つクラスに割り当てる必要があります。例については、[デフォルトエンジン](https://github.com/nesquena/rabl/blob/master/lib/rabl/cache_engine.rb) を参照してください。
`perform_caching` を `true` に設定すると、キャッシュが実行されます。Rails を使用している場合はこのオプションを無視できます。これは Rails の `config.action_controller.perform_caching` と同じです。
`cache_sources` を `true` に設定すると、パフォーマンス向上のためにテンプレートの検索がキャッシュされます。キャッシュは、アプリケーション内で `Rabl.reset_source_cache!` を実行することで手動でリセットできます。
`cache_all_output` を `true` に設定すると、コレクションの一部として使用される個々のテンプレートを含むすべてのテンプレートが個別にキャッシュされます。さらに、child、glue、partial 内のものも個別にキャッシュされます。単一のテンプレートのみをキャッシュするには、以下の「Caching」のセクションを参照してください。
`escape_all_output` を `true` に設定し、ActiveSupport が利用可能な場合、属性の出力は [ERB::Util.html_escape](http://corelib.rubyonrails.org/classes/ERB/Util.html) を使用してエスケープされます。カスタムノードはエスケープされないため、`ERB::Util.h(value)` を使用してください。
`view_paths` にパスを設定すると、アプリケーション内のすべての rabl テンプレートに対してこのビューパスがチェックされます。特に、エンジンに Rabl を含め、別の Rails アプリ内でビューパスを使用する場合は、このパスに追加してください。
`raise_on_missing_attribute` を `true` に設定すると、Rabl が存在しない属性をレンダリングしようとするたびに RuntimeError が発生します。それ以外の場合は、属性は単に省略されます。開発中にこれを true に設定するとコードの堅牢性を高めるのに役立つかもしれませんが、本番コードで `true` を使用することは推奨されません。
`replace_nil_values_with_empty_strings` を `true` に設定すると、`nil` であり通常はレスポンスで `null` として表示されるすべての値が空文字列に変換されます。
主要な JSON エンコーディングエンジンとして [oj](https://github.com/ohler55/oj) を使用したい場合は、Gemfile に追加するだけです:```ruby
# Gemfile
gem 'oj'
そして、RABLはそのエンジンを自動的に使用して、JSONレスポンスをエンコードします。独自のカスタムjson_engineを設定します。これは、RubyデータからJSONに変換するためのdumpまたはencodeメソッドを定義します:```ruby
config.json_engine = ActiveSupport::JSON
### フォーマット設定 ###
RABL は MessagePack、BSON、Plist の設定をサポートしています。詳細は [フォーマット設定](https://github.com/nesquena/rabl/wiki/Configuring-Formats) ページをご覧ください。
## 使用方法 ##
### オブジェクトの割り当て ###
テンプレートで使用するデータオブジェクトを宣言するには:```ruby
# app/views/users/show.json.rabl
object @user
またはオブジェクトのエイリアスを指定してください:```ruby object @user => :person
または、オブジェクトのコレクションを渡す:```ruby
collection @users
# => [ { "user" : { ... } } ]
または、コレクションのルートノードラベルを指定してください:```ruby collection @users => :people
あるいは、コレクションに対して子ラベルとルートラベルの両方を指定することもできます:```ruby
collection @users, :root => "people", :object_root => "user"
# => { "people" : [ { "user" : { ... } } ] }
これはレンダリングのデフォルトデータとして使用されるか、またはオブジェクトルートを明示的に無効にします:```ruby collection @users, :root => "people", :object_root => false
ルートレベルのレスポンスがどのオブジェクトにも直接マッピングされない奇妙なケースもあり得ます:```ruby
object false
node(:some_count) { |m| @user.posts.count }
child(@user) { attribute :name }
そういった場合、オブジェクトに'false'を割り当て、ノードを自由形式で構築できます。