長いこと、Ruby on Railsを使って様々なサービスやアプリのバックエンドを作ってきたが、今年に入ってからRailsの代わりにParseを使う場面が増えてきた。機能面や拡張性の問題など何かと不安があったのだが、半年以上実際に稼働しているサービスで使用してみた結果、期待以上の好印象を持っている。
Parseとは
Parseはスマホアプリ用に最適化されたBaaS(Backend as a Service)の一つ。多くのスマホアプリで使われるような、ユーザ認証、プッシュ通知、アクセス解析、そして独自データの保存・管理をするためのAPIがあらかじめ用意されており、自分でサーバー側のコードを書いたり、それを稼働させるためのサーバーの設定をしなくても、SDKを入れるだけでこれらの機能を使えるようなサービスだ。
長い間、自分でアプリを作る時は、これらの機能を提供するためにRuby on Railsでバックエンドを作っていたが、毎回同じような実装を繰り返しているような気がしたので、もっと効率的に実装する方法がないか調べていた際に見つけた。独自処理が必要な場合を除いて、コードを書かなくて良い、というのはとても革新的に見えたが、機能的に十分なのか、やりたいことができなくなった時にベンダーロックインが発生して厄介なことになるのではないか、という不安があったのだが、半年前に自分のVPSサーバーで障害が発生した際に復旧がえらく大変だった(数年前に作ったプロジェクトの環境設定を、いろいろ思い出しながらやっていくのは辛い)ことをきっかけに、本格的にParseの利用を検討するようになった。
Parseのいいところ1: 立ち上がりが非常に早い
Parseではサーバーのコントロールパネル上でデータ構造を設定すると、コードを1行も書くことなく、それに対応したREST APIが自動的に用意される。CREATE, UPDATEは許可するが、DELETEは許可しない、などの権限周りもコントロールパネルで設定するだけだ。
REST APIは、設定したら即座にクライアントから利用できる。Ruby on Railsの場合、Herokuを使ったとしても、ローカルにプロジェクトを作成してモデルのジェネレートをして、それに対するAPI層を実装してからHerokuの設定・デプロイをして…という手順を踏まなければ、実際にサーバー上で稼働するAPIとして使えるようにならないが、Parseでは丸ごとこのプロセスが省略される。開発初期の段階ではローカル環境で動けば良いのではないか、という意見もあるかもしれないが、個々の開発環境でローカルにサーバー環境を作る手間を省けるので、実際すごく便利だ。特に、複数人で開発するような場合には。
そして、そのAPIにアクセスするためのクライアントSDKがとても良くできている。iOS / Android / JavaScript…環境ごとにクライアントSDKが用意されている。AFNetworkingを使ってAPIを叩きに行き、受信したJSONをパースして…といった処理を自前で書く必要がないので、クライアント側も実装の手間が大分減る。
素敵なのは、サーバー上のデータ(テーブル)にアクセスするためのAPIだけでなく、ユーザ登録・ログイン・ログアウトあるいは、プッシュ通知関連の処理などの一般的なスマホアプリで共通して使われるような機能が用意されていることだ。それも含めて、Parseを使ったプロジェクトでは、開発の最初の段階でかかるコストが圧倒的に小さい。
Parseのいいところ2: メンテナンスが非常に楽
とにかくコードの全体量が少なくなるため、後で実装を把握するのが楽だし、バグも産みにくくなり、メンテナンスコストが小さくなる。
それこそ、単純なREST APIとユーザ認証を使うだけであれば、サーバーのコントロールパネル上でデータ構造の設定をするだけで、サーバー側のコード0行で運用することもできる。Ruby on Railsを使ったプロジェクトでも、他のフレームワークに比べたらコーディング量は少ないが、直接手を加えない部分でもジェネレータが生成したコードがあったりして、それも含めると全体のコードの量はどうしてもそこそこの長さになってしまう。ジェネレータが生成したコードは、普段直接いじることが少なくても、ライブラリのアップデートの際に副作用を生んだりするが、Parseの場合はそういうコードもないので、非常にスマートだ。
そして、インフラ的な部分は完全にお任せ(むしろいじれる部分がない)なので、負荷的な点で適切なプランを選んでおくというようなこと以外、基本的に何も気にしなくて良い。
Parseの微妙なところ1: バックグラウンド処理の自由度が低い
Parseでは、サーバー側で非同期処理を行うのが難しい。アップロードされたファイルの加工のような重い処理を別プロセスで実行させたり、あるいは指定したタイミング(30秒後、とか)で任意の処理を行う、といったことができない。
一定時間毎にスクリプトが動くように設定することはできるため、「ポーリングをして実行するべき処理があったら実行する」みたいなことはやろうと思えば可能だが、とても面倒臭い上に、1分より短いスパンで実行することができない。
最大1分程度の時差・ウェイトなら許容できる、という場合なら問題はない。ただ、例えば「非同期でTwitter APIを叩いて結果を取ってくる」というようなケースでは、1分の時差というのは結構なストレスになる。回避方法がないわけではないが、途端に非常に不自然で複雑な実装となってしまう。
Parseの微妙なところ2: サードパーティライブラリが使えない
簡単なイメージ処理(クロップや拡大縮小程度)程度であれば、用意されているモジュールを使えばできるが、それ以上のことは基本的にはできない。外部ライブラリ(ImageMagickとかMeCabとか)を使いたい場合、外部に別のサーバーを自分で立ててインターフェイスを用意して通信させる以外に、方法がない。
Parseの微妙なところ3: なんだかんだで、結局コードは多少書くことになる
データ構造の定義だけでREST APIが使えるようになる、というのが最大のメリットなのだが、リリース段階までには、結局バリデーションなどの目的で多少のコードを書くことになる。REST API一発では実現できない処理(ルームにいるメンバー一覧を取得してきて、それぞれにプッシュ通知を送る、とか)も、iOS / Androidそれぞれのクライアント側で実装するとDRYではなくなってくるので、サーバー側にAPIを用意する形になる。
そして、このサーバー側のコードを実装する仕組み(CloudCode)が使いにくい。BaaSとして提供されていることの弊害として、ローカル環境にParseサーバーと同等の環境を再現することができないので、「コードを書いたら、サーバーにデプロイして動作確認」という開発フローになってしまう。
そのためにStagingあるいは開発用の環境を作る必要が出てくるが、データ構造をシンクあるいはマイグレーションするような仕組みは特になかったりで、非常に効率が悪い。
Parseの微妙なところ4: その他細かい問題
他にも、REST APIでデータを引いてくるときにランダム順(ORDER BY RAND()のようなもの)が使えない、テーブルのJOINができない(代わりにサブクエリーを使う)などの諸問題があって、不便に感じることはあるが、大した問題ではないので省略。
結論: それでもParseは、試してみる価値がある
それでもParseは期待していたよりもすごく良い。上に羅列したような問題点もあって、Parseはあらゆるプロジェクトに対応できるというものではない。実際、この半年に作ったアプリ・サービスでも、結局Parseの利用を諦めてRuby on Railsを使ったケースもあった。
だが、マッチしているプロジェクトで使うと、圧倒的に開発・メンテのコストとストレスが小さくなる。半年ほどいろいろなプロジェクトで使ったみた感想として、強く実感している。使い始めた頃、Ruby on Railsで作る代わりにParseを使う、という視点で使っていると問題に直面してストレスを感じることが多かったのだが、慣れてくると上記Parseの特性を踏まえた上での設計をするように頭が切り替わってくる。そうなると、本当にParseは強力だ。Parseを使う上での制約というのは、それまでの多くのスマホアプリの実装パターンを踏まえた「よく考えられた制約」なので、そこに従うのは悪いことではない。
だから、まだ試したことがない人は是非一度試してみるといいと思う。