Ruby on RailsのJSON API Responseについて考える。あるいはjbuilderについての個人的違和感とその解

この記事は

Ruby on Rails Advent Calendar 2018 の12/21の記事になります。

タイトルの通り、Ruby on Railsを利用したJSON形式にResponseについて考える記事です。

JSON Responseについて

RailsでJSON Responseを生成する際にはjbuilderを利用している方が多いのではないかなと思っています。

$ rails new 

をした際にもデフォルトでGemfileに記載がありますね。

ですが、個人的にjbuilderは利用したくないと思っています。

1. 独自のDSL

以下はjbuilderのrepositoryのREADMEに記載されているサンプルです。

# app/views/messages/show.json.jbuilder

json.content format_content(@message.content)
json.(@message, :created_at, :updated_at)
json.author do
 json.name @message.creator.name.familiar
 json.email_address @message.creator.email_address_with_name
 json.url url_for(@message.creator, format: :json)
end

if current_user.admin?
 json.visitors calculate_visitors(@message)
end

json.comments @message.comments, :content, :created_at
json.attachments @message.attachments do |attachment|
 json.filename attachment.filename
 json.url url_for(attachment)
end

人によると思いますが、個人的にはjbuilderのDSLには違和感があります。
これは個人差だと思いますが、下記のif文を見てみます。

if current_user.admin?
 json.visitors calculate_visitors(@message)
end

current_userがadminであれば、生成されるJSONにvisitorsというattributeが追加されます。
逆に言えば、current_userがadminではない場合は、visitorsというattributteは付きません。

サーバサイドであればJSON Responseを返すだけで後はクライアント(JavaScript、iOS・Android etc)でいい感じにやってくれ。
という事も出来ますが、userの属性によってattributeがついたり消えたりするのはクライアントのコードが複雑になることに繋がります。

2. 遅い

2014年とだいぶ古い記事ではありますが、

Object#to_jsonと、JBuilderの速度を比較した記事があります。

to_json: 0.2 ms
JBuilder: 129.0 ms
JBuilder with OJ: 88.0 ms

一目瞭然ですね。

似たような違和感を抱いている人はいるのか、redditにもなぜjbuilderを使うのだ?というスレッドが立っています。

ではどうするのか。

fast_jsonapi

一つの解として、ActiveModelSerializerというgemがあります。

が、2018/12 現在、ActiveModelSerializerは積極的にメンテナンスはされていません。

The 0.10.x version has become a huge maintenance version. We had hoped to get it in shape for a 1.0 release, but it is clear that isn't going to happen. Almost none of the maintainers from 0.8, 0.9, or earlier 0.10 are still working on AMS. We'll continue to maintain 0.10.x on the 0-10-stable branch, but maintainers won't otherwise be actively developing on it.
We may choose to make a 0.11.x ( 0-11-stable) release based on 0-10-stable that just removes the deprecations.

issueもPull Requestも溜まっている状態です。

ではどうするのかという話に戻ってしまうのですが、今であればNetflixが作成したfast_jsonapiというgemを利用するのがいいのかなと思います。

これは、ActiveModelSerializerからインスパイアされて作成されたGemで、ActiveModelSerializerよりも早く、なおかつメンテナンスもされています。

まとめ

gRPCや、GraphQLが出てきていますが、JSON APIはまだまだ利用する機会が多いと思います。何かのお役に立てれば幸いです。

Software Engineer. https://teitei-tk.com