はじめに
こんにちは、Half-Vaccinatedなフロントエンドエンジニアのkitagawaです。接種2回目にビビりながら今から備えています。
この度トレタの新しいサービスとして、トレタO/X(トレタオーエックス)が正式リリースされました。O/Xは「Order Experience(注文体験)」の略で、飲食店に来店したお客様がご自身のスマートフォンで注文から決済までを行えるモバイルオーダーアプリです。
サービスの本格立ち上げから今回のリリースまで、約1年ほど主にバックエンドのマネジメントに携わってきたので、その振り返りとして開発内で行った数々の挑戦について、この記事では紹介しようと思います。
サービスの詳細や背景については代表のひとしさんのブログをぜひご一読ください。
トレタO/Xの特徴
タブレット据置機でのオーダーや、テイクアウトのモバイルオーダーなど、オーダーアプリを目にする機会は近年急激に増えてきました。
そんなレッドオーシャンの中でトレタO/Xの最大の特徴は、導入する各飲食法人ごとにUIを完全カスタマイズした専用アプリを開発している点です。これはSaaSとして提供してきたトレタの予約台帳とは全く逆のアプローチで、予約台帳では個社ごとのカスタマイズは行わないポリシーで行っていましたが、今回は逆に完全に個社向けに作り込むアプローチをとっています。
事例に沿ってご紹介していきます。
最初に導入したのはワンダーテーブルさまのよなよなビアワークスで、クラフトビールのよなよなエール公式のビアレストランです。そのためアプリでは、画面のレイアウト、フォント、カラー、注文後のアクションなど、細部までよなよなビアワークスの世界観を表現するために作りこんでいます。
ダイヤモンドダイニングさまの焼鳥IPPON向けアプリでは、好きな焼き鳥の組み合わせや味付けを串一本ずつ自由にカスタマイズして注文する仕組みや、各々が注文した分を会計できる個別決済など、店舗開発の時点から携わらせていただき新しい注文方式をアプリへと落とし込んでいきました。
これらを実現するため、開発の構成としてはフロントエンドとバックエンドの明確な分離を行いました。Shopifyなどのヘッドレスコマースを参考にし、バックエンドは注文と決済をコアにしたAPIを提供するSaaSの構成となっています。
フロントエンドは各社ごとに個別に開発し、メニューなどのマスターデータはCMSなどを利用して各アプリごとに持たせています。導入する店舗は居酒屋やカフェ、ファミリーレストラン、ファストフードなど、業態や店舗形態に応じて様々なメニューの構造や注文フローを想定した結果、画一的なデータ構造ではそれらに対応できないと考え、マスターデータを共通バックエンドでは扱わずに各社ごとに最適なデータ構造のマスターを持つことで、柔軟なUI表現を可能にしています。
トレタO/Xの技術スタック
トレタO/Xの技術スタックは、プロトタイピングを隔てて、製品版向けに一度リプレイスを行っています。
PoC期間のプロトタイプでは開発スピードが求められるため、フロントエンドにFlutter、バックエンドにFirebaseを採用しました。フロントは主に来店したお客様が利用するユーザー向けアプリと、店内のホールスタッフが利用するスタッフ向けアプリの2種類があります。両方ともFlutterで作っていますが、Flutter Webを使用しています。
ユーザー向けアプリは来店時にお客様自身のスマホでQRコードを読み込んで開始してもらう流れとしているため、アプリインストールの強制は避けるためにWebアプリとしています。
スタッフ向けアプリに関してはそういった制約はないのですが、ネイティブアプリだとアップデートごとにiOSやAndroidのマーケットへの審査が必要となってしまうため、開発スピードを優先してこちらもWebアプリとしました。ネイティブの機能が必要になったときにiOS/Androidアプリへ切り替えられるようにFlutterを採用しています。
プロトタイプ後の製品版では、プロトタイピングで検証したデータ構造やドメイン境界を基に、バックエンドは各種ドメインに分割したマイクロサービスにしています。トレタでは長らくRuby on Railsを使用したモノリシックなシステム構成が主だったので、トレタとしては今回初めてのマイクロサービスを採用となりました。
マイクロサービスは銀の弾丸ではないことは肝に命じた上で、マイクロサービスを選んだ経緯についてご紹介します。
メンバーの技術スタックに合わせた並行開発
限られた開発リソースの中でいかに早く開発できるかという点で、各自が独立して開発を進められるように、マイクロサービス単位でチームの分割を行いました。(弊害として、システム間の結合時にはコミュニケーション不足による問題も多く発生しました...)
プログラミング言語や各技術要素の選定には、それらの特性を踏まえつつ、挙がった候補の中から何を使うかはメンバーの技術領域に合わせて選んでいます。
例えば、Node.jsはフロントエンドのメンバーでも扱いやすいため、フロントとバックを兼任する場面で選択しています。Goについては、Rubyと違い型付きという利点があるため、社内では最近RubyからGoを選択する場面が増えています。またデータベースには、強いACID特性を持つDatomicを使うために社内ではあまり使われないClojureも使用しています。
サービスの再利用
トレタO/Xの開発を開始をする時点で、コロナによる飲食業界の急激な状況変化に対応すべく、トレタでは多くの新規プロダクトの開発を行い、クローズを行いました。トレタは飲食業界のVertical SaaSを目指すため、各プロジェクトで似たような機能が車輪の再発明されていた状況がありました。そこから、今後別プロジェクトでも再利用が行えるようにトレタO/Xに捉われない形で個々サービスの設計を行っています。
モノリシックからの脱却
やはりモノリシックな予約台帳での教訓としての一面があります。
エンハンスを長く続けていくと、どうしても当初の設計とは外れた機能追加が行われてしまうものです。都度うまく負債を返却できるとよいのですが、歪みが積み重なるとがんじがらめになり、追加開発が日に日に難しくなります。
マイクロサービスで綺麗に解決するわけではないですが、開発初期から疎結合を前提にドメイン境界を意識した設計を行っておくで、この後のエンハンスのしやすさは大きく変わってくると感じています。
さいごに
トレタO/Xはまだリリースされたばかりのプロダクトです。導入店舗数を増やしつつ、各店舗が表現したいメニューブックを実現するために、より深く入り込み洗練されたUIへの磨き込みを行っていきます。 また、トレタO/Xとトレタの予約台帳や他のサービスとも連携し、お客様が店探しをする段階から来店して退店した後までの一環のライフサイクルをトレタが提供する未来も描いています。
そんな開発に参画してくれる開発メンバーを募集しています。各ポジションがオープンになっていますので、興味をお持ちになったらまずは気軽に話を聞きにきてください。