RESTful Hypermedia API サーバサイド編 – roar
モバイルアプリサービス部の五十嵐です。
サーバサイド編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の開発が省力化できそうです。