sou's blog

落ち着いた華やかさがあり、上品に明るく陽気なさまを表す。

オープンソースのmastodonからみるRails + React構成や採用されているライブラリについて

mastodonについて

mastodonという新興SNSが国内でも流行りだしています。フェーズとしてはまだイノベータからアーリーアダプターが様子を見てるって感じかなと個人的には思います。

mstdn.jpという日本ドメインインスタンスでは、現時点(2017/4/22)で全インスタンスと比べても世界一のユーザ数を誇っています。ただ、実際に投稿内容を見てみるとユーザもまだテスト投稿したりという感じのようです。(もっとコアなドメインインスタンスだとそのコンテキストの投稿がもっと盛んにされているのかもしれないですが)

このサービスの面白いところは、分散型ネットワーク+OSSというところなのかなと勝手に解釈しています。つまり、個人もしくは企業がTwitterのようなSNSサービスを(手軽に)独自運営していけてそれが本家の改善にもつながる仕組みになっているところに魅力があります。もう少し具体的に言うと本体のソースコードOSSなので大抵はForkしたものをデプロイすることになると思うのですが、そのインスタンス特有の機能を入れて本体とは少し違ったアプリケーションにしたり、場合によっては追加した機能や見つかったバグの修正を本体側にPull-Requestするなどサービス自体が分散して成長していく仕組みが取り入れられているのです。

コードを覗いてみてみる

前置きが少し長くなりましたがコードを実際に見てみるとRails+Reactで構成されていることがわかります。流行りのWebアプリケーションの構成だと思うので、参考になるところが多いです。

サーバーサイド構成

Rubyは2.4.1、Railsのバージョンは現時点で5.0.2で比較的新しい構成であることがわかります。

ruby '2.4.1'

gem 'rails', '~> 5.0.2'
APIの管理

app/controllers/api_controller.rbにApiControllerと言う基底クラスを定義しています。また、app/controllers/api/v1配下に実際のAPIをApiControllerクラスの具象クラスとして配置しています。これでいわゆるAPIのバージョニング管理をしているようです。

concernの実装

model/concerns配下では以下のような共通の振る舞いが定義されています。

cacheable.rb
paginable.rb
streamable.rb
targetable.rb

paginable.rbを見てみると内部的にarel_tableを使用してqueryを組み立てていることがわかります。

scope :paginate_by_max_id, -> (limit, max_id = nil, since_id = nil) {
      query = order(arel_table[:id].desc).limit(limit)
      query = query.where(arel_table[:id].lt(max_id)) unless max_id.blank?
      query = query.where(arel_table[:id].gt(since_id)) unless since_id.blank?
      query
}

フロントエンド構成

app/assets/javascripts/components配下にReactのコードが配置されています。JavascriptはECMAScirpt 2015記法で書かれています。Gemfileをみると以下の記述が確認できます。

gem 'react-rails'
gem 'browserify-rails'
gem 'autoprefixer-rails'
React + Redux

reactをrailsに導入するアプローチはいくつかありますが、mastodonではasset_pipline上にReactをのせるためreact-railsを採用しています。また、browserifyでbabelを使ってコンパイルするようにbrowserify-railsを採用しています。Reactでのスタイル適用はインラインでもscssでもどちらにも書かれています。

Ajax

ajax通信ライブラリとしてはaxiosが採用されています。ただし、使用するにはapi.jsxというラッパーモジュールから呼び出しています。

レンダリング対策

react-addons-pure-render-mixinが採用されています。

途中。気づいたら追記