9isというサービスを開発した話
去る1/9は一休さんにちなんで、クイズの日と呼ばれているようです。そんなクイズの日に9is(クイズ) - みんなでもっとおもしろくできるというサービスをリリースしました。これはペパボで毎年開催している、お産合宿という名の開発合宿で開発したものです。お産合宿後も、誰かがやる気が高まった時にイイ感じに進める。というゆるい感じで開発を進めていましたが、晴れて1/9に正式リリースということにしました。
リリースといっても、特別何もしてないんですが、これを機にサービスの紹介をします。
9isとは
某感謝祭風のクイズができるサービスです。自分でクイズを自由に作れて、参加者を集いリアルタイムに回答・早押しランキングを表示することが出来ます。
なぜWebアプリ?
今なぜ、ネイティブアプリではなく、Webアプリを作ったのかというと、ブラウザやフロントエンド周りの技術の進化によって、ネイティブにWebが近づこうとしています。その中で、ネイティブよりもWebのほうが適した分野というものがあり、その1例となるようなアプリを作りたかったというのが、発端です。
SLICEというGoogleの人が言っていたWebの持つ特徴を表した言葉があって、ざっくりいうと
- Secure: セキュリティ上の安全性が比較的高い
- Linkable: URLによって一意にページやコンテンツを特定できる
- Indexable: Linkableの結果、検索可能になる
- Composable: iframeやJSを埋め込むだけで、別サービスを使うことができる
- Ephemeral: install不要で、URLにアクセスするだけで必要な機能が使える
この中のLinkableでEphemeralな点はWebの大きな魅力なので、その点を活かしたもので、面白そうなものはないかと考えていきました。今回の9isでは、幹事の人から参加者へ参加用のURLをシェアして、そこにアクセスするだけでクイズを楽しめる。という形で、それを活かせているかと思います。
9isの裏側
この5人で開発を進めました。
- デザイン(キャラクタ): @yasuaki818
- デザイン(画面): @mugimemo、@oremedia
- API: @mapyo
- フロントエンド、WebSocket: 自分@tsuchikazu
それでは、システム面を紹介していきます。
全体構成
9isは、Renderingサーバ / APIサーバ / WebSocketサーバ の3つのサーバから構成されています。
Renderingサーバ
https://9is.party でアクセスされる一番フロント側のサーバが、Renderingサーバです。開発当初は、Server side renderingをしようと思っていたので、こんな名前にしているんですけど、やる必要ないし、ちょっと面倒だし、3年後ぐらいには廃れていそうな技術だと思ったので、やるのをやめてしまいました。
今、Renderingサーバでは静的なファイル(HTML、JS、CSS等)を返すだけのexpressをherokuで動かしています。もはや完全に静的ファイル配信なので、CloudFlareというCDNも使っています。CloudFlareのスゴイところが、なんと無料でSNIを利用したSSLまで提供してくれることです!!これによって、無料で独自ドメインのSSLが実現できました。
配信されるフロントエンドでは、ES6(2016)で開発してBabel + browserifyでbuildしてます。ViewにはReact、Fluxにはyahoo/fluxibleを使いました。(Server side renderingを諦めた今、fluxibleである必要が無いんですけど) 今回、始めてReactとFluxを触ったんですけど、ただ単に表示する系なら簡単でいいんですが、Form周りがどうすればいいのかわかりにくく苦労しました。今後、部分的にAngular2を試していきたいと思っています。
APIサーバ
APIサーバは、@mapyoによってRailsで開発されました。Sqale - 開発者のためのホスティングサービス【スケール】で動かしているようです。
Parse.comのようなBaasを利用するか。という話も上がったんですが、社内の人からBaas使っていたけど、やりたいことが実現できずに結局自作した。というような話も聞き、自作することにしました。クイズのランキング集計などでは、ちょっと変なことをしているので、やはり自作してよかったんじゃないかなと思っています。(そうでないと、フロント側で無理やり頑張る。という形になっていたかも)
開発中はApiaryを使って、ドキュメント化しながらAPI仕様を詰め、そのままAPIのモックサーバとして活用できたので、なかなか便利でした。
WebSocketサーバ
WebSocketサーバは、主に幹事用の画面と、クイズ参加者用の画面遷移を同期させるために使っています。
これもPusherなどの外部サービスを使おうとしたんですが、無料枠の同時接続数が少ないのが気になって、Socket.IOで自作してみたらすんなり動いたので、そのまま自作版を使うようにしました。これもherokuに乗せているんですけど、どこまでスケールできるかわからないので、あとで外部サービスを使うようになるかもしれないです‥
構成まとめ
このように、9isでは3つのサーバにわけて構成しています。これらは、1つにまとめることもできましたが、あえて分けるように設計しました。1から作るとき今ならこういう構成にするよね。という感じでわけたんですが、その結果として、
- それぞれのロールでマッチしている言語やフレームワークを選定できた
- 特定のロールだけ外部サービスを使うようにできた(実際にはやらなかったけど。逆に今後、外部サービスに任せることも可能)
- 今後、特定のロールだけスケールすることができる
micro servicesで言われているような利点は感じることができました。わける粒度について今回のように、外部サービスで提供されているような粒度。例えばHerokuのAdd-Onで提供されているような粒度にする、というのは一ついい基準になりそうです。
わけることによる弊害はあまり感じなかったんですが、今回インフラは全てPaaS(heroku & Sqale)を利用できた点と、開発者が2人しかいない点が理由かなと思います。管理するサーバ数が増えるので、単純にインフラコストは増えそうですが、PaaSを利用すればそこは全く感じませんでした。あとはシステム間の連携について、認識齟齬が出てきそうですが、そもそも2人しかいないし、APIとそれ以外で役割をわけたのでその間にApiaryがあったおかげで、うまくできたかなと。実際に仕事でやるとなると、IaaSに載せたり、開発者が増えるので、また事情は変わってきそうな気がします。
最後に
9isは、完全に手段を目的化したサービスなんですが、結構おもしろいサービスに仕上がっているので、是非使って見てください。今後、これで小銭も稼いで行きたいんですけど、なかなか難しいので、新たな技術の遊び場として今後も活用して、もっといいサービスにしていきたいです。
API担当の@mapyoのブログもどうぞ! 9isというサービスをリリースした - 画竜点睛を衝く@mapyo
[amazonjs asin="4873117194" locale="JP" title="入門 React ―コンポーネントベースのWebフロントエンド開発"]