この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
モバイルアプリサービス部の五十嵐です。
サーバサイド編3回目はroarを紹介します。サーバサイド編としていますが、roarにはクライアント側の機能もあるので併せて紹介します。
roarとは
APIサーバ
roarはこれまで紹介してきたgarageやactive_model_serializerと同様に、JSONなどのAPIをレンダリングします。APIのレンダリングにはRepresentableというgemを使用しています。Representableはhypermedia APIをレンダリングするためのDSLで、active_model_serializerのSerializerと同じような位置づけです。フォーマットは、JSON、JSON-HAL、JSON-API、XMLに対応しています。
APIクライアント
roarはAPIのHTTPクライアントとしても機能します。Representableを使うことでActiveRecordのオブジェクトをリクエストのJSONにパースしたり、レスポンスのJSONをActiveRecordのオブジェクトにパースすることができます。また、HTTPSや証明書による認証などセキュアな機能にも対応しています。
双方向
このように、リクエストのパースやレスポンスのレンダリングをRepresentableが担うことで、サポートされているフォーマットを使うだけでActiveRecordのオブジェクトをデータとしてやりとりすることができます。イメージを簡単に描いてみました。
サンプル
Rails Webookさんが非常に丁寧なサンプルと解説を書かれているので詳細はそちらを参照していただくとして、この記事では重要なパーツだけを簡単に紹介したいと思います。
Representer
SongというオブジェクトのAPIをレンダリングする部分です。active_model_serializerのserializerとよく似ていますので、active_model_serializerの記事を見ていただければどういうものか理解いただけるかと思います。フォーマットを指定する場合は、include Roar::JSON::JSONAPI
のようにフォーマットをインクルードします。
# app/representers/song_representer.rb
require 'roar/json/json_api'
module SongsRepresenter
include Roar::JSON::JSONAPI
type :songs
property :id
property :title
has_one :composer
has_many :listeners
link "songs.album" do
{
type: "album",
href: "http://example.com/albums/{songs.album}"
}
end
link "songs.album" do
{
type: "album",
href: "http://example.com/albums/{songs.album}"
}
end
meta do
property :page
property :total
end
end
サーバ側
ActiveRecordのSongクラスに対してSongRepresenterをextendすることで、to_json
やfrom_json
が使えるようになります。
to_json
は指定されたRepresenterの通りにレンダリングしたJSONを返します。GETメソッドなどのAPIのレスポンスで使います。
song = Song.new(title: "Fate")
song.extend(SongRepresenter)
song.to_json #=> {"title":"Fate"}
from_json
はJSONからActiveRecordのオブジェクトに変換します。POSTメソッドなので要求を受け取った時に使います。
song = Song.new
song.extend(SongRepresenter)
song.from_json('{"title":"Linoleum"}')
クライアント側
データの取得の場合はSongオブジェクトを生成してgetメソッドを実行するだけで、結果がsongの中に入り、ActiveRecordのインスタンスとして利用できます。
song = Client::Song.new
song.get(uri: "http://localhost:4567/songs/1", as: "application/vnd.api+json")
データの登録などについても同様です。
song = Song.new(title: "Roxanne")
song.post(uri: "http://localhost:4567/songs", as: "application/vnd.api+json")
所感
いかがだったでしょうか。これまで見てきたものはサーバサイド側だけでしたが、roarはクライアント側もサポートしているので、Railsアプリケーション同士の連携や、RailsのAPIとRubyのクライアント用のライブラリをセットで提供することが容易になります。また、対応しているJSONフォーマットであれば受信したリクエストのパースもしてくれるので、APIの開発が省力化できそうです。