トレタ開発者ブログ

飲食店向け予約/顧客台帳サービス「トレタ」、モバイルオーダー「トレタO/X」などを運営するトレタの開発メンバーによるブログです。

TORETA TECH UPDATE #1 イベント後記

こんにちは、トレタ VPoEの北川です。

先日、トレタ主催のエンジニアイベント「TORETA TECH UPDATE #1 -飲食を支えるフロントエンド」を開催しました。 ご参加いただいた皆様、大変ありがとうございました。 また、台風の影響によりオフラインの開催からオンラインの開催へ急遽切り替えさせていただき、参加予定だった方にはご迷惑をおかけして大変申し訳ございませんでした。

toreta.connpass.com

今回のイベントはトレタとしてコロナ禍以降にイベントを行う機会が減って、約5年振りのイベント開催でした。 自分としてもイベントを企画するのは今回が初めてだったので、今回のイベントを振り返りつつ、イベント開催をしてみようと考えている方向けに参考になりそうなことを書き記しておこうと思います。

集客の悩み

企画が動き始めたのは約3ヶ月前の6月頃で、経緯としてはこちらの記事で書いております。 当日までの準備で一番苦労した点は集客でした。

今回は採用につなげたいという目的もあったので、オフライン開催として開催の1ヶ月前にConnpassにイベント掲載をしました。 その日に登録いただいた参加者は5名程度。 イベント開催をよくやっている方からいただいたアドバイスとしては、参加者が集まるピークはイベント掲載時とまで言われていました。 弊社はまだまだ知名度も低いので集客力がないのは承知でしたが、正直これはまずい…ということで掲載内容を知り合いなどに見てもらい改善点を検討しました。

タイトルのキャッチーさ

今回のタイトルは「TORETA TECH UPDATE #1 - 飲食を支えるフロントエンド」ですが、たしかに指摘されてから見ると何のイベントかわからないのと興味も引きづらいです。 フロントエンドという部分で大まかなターゲットは分かりますが、どういうテーマかが見えてこません。 「飲食」という部分もエンジニアの興味を引くワードとしては厳しいです。 なのでこのタイトルではConnpassで見かけてくれた人をアトラクトすることはできず、実際に掲載日に応募いただいた方の経路はSNS経由でした。

改善点としては例えば、「Next.jsでのリアーキテクト」など、具体的な内容、技術要素、日頃抱えている課題に直結するなど、タイトルを見てわかるのが良いのかと痛感しました。 タイトルを途中から変えるのは憚られたので今回はそのままにしましたが、次回以降は改善しようと思います。

オフライン勉強会文化の移り変わり

これは20代の若い方からの意見としていただきましたが、オフラインのみしかない勉強会やイベントは人を誘ってでないと1人では行きづらい、とのことでした。

これについては自分の感覚と大きくギャップを感じましたが、コロナ禍以前を知らない人たちからするとオフラインでの勉強会は参加者目線ではハードルが高く、オフラインの場合でも同時にオンライン参加がないとハードルが高くて参加しづらいとのことでした。

弊社も勤務はフルリモートな環境なので、この為に外出するのは腰が重い、業務都合で時間が取れなそうならオンライン参加にしたい、という気持ちはたしかにわかります。 今回は思いがけず台風10号の影響でオンライン開催に途中で急遽切り替えましたが、おかげでオンライン参加でたくさん応募いただくことができ、最終的には35名の参加まで募ることができました。

当日の振り返り

当日は2名のトークと、その後にQ&Aという構成で行いました。

フロントエンドエンジニアの武市さんの登壇資料 speakerdeck.com

クレスウェア株式会社の奥野さんの登壇資料 speakerdeck.com

Q&AにはSli.doを利用したところ、登壇中に20件の質問をいただくことができQ&Aが非常に盛り上がりました。 いただいた質問をいくつかピックアップして紹介します。これらいただいた質問に関してはこのブログ内で順次回答していこうと思います。

  • AppRouter移行の作業にはどれくらいかかりましたか?
  • AppRouter移行後の効果はどれほどありましたか?
  • PagerRouter時代のコンポーネントとAppRouter移行後のRSCとが混在している状態での認知負荷などはありますか?
  • FeatureFlagの管理方法はどうしていますか?利用しなくなったら消しますか?
  • フロントエンドのテストはどの粒度でやていますか?ツールは何を使っていますか?
  • Next.jsのデプロイ先の構成やサーバーコストを知りたいです
  • リリースサイクルやQA体制はどうしていますか?

やはり実際にやってみてどうだったか、運用してみてどうだったか、といった事例の詳細に関心をいただけたかと思います。 ウチはこうやってるけどヨソではどうしてます?というのは私達もよく気になることなので、これからもウチではこうやってるよ!というのを今後も発信し続けていこうと思います。

次回の開催

今回のタイトルを「TORETA TECH UPDATE #1」としたので、「#2」も近々やりたいと考えています。テーマはまだ何も決まっていませんが、「フロントエンド x 〇〇」をテーマに何かできないか検討中です。いただいた質問やアンケート回答を見ていると「テスト」であったり「プロジェクト進行」みたいな部分をもっと知りたいという声をいただいたので検討させていただこうと思います。

ぜひ次回開催時の際にも沢山のご参加をお待ちしております。

マイクロサービス・リアーキテクト

こんにちは、トレタ VPoEの北川です。

先月にモバイルオーダー「トレタO/X」の新機能として、NECモバイルPOS連携をリリースしました。今回の記事ではその時の開発を振り返り、開発の裏側について紹介しようと思います。

toreta.in

外部POSとの連携

モバイルオーダーと切っても切れない関係にあるのが「POSレジ」です。POSレジとはいわゆる会計のレジのことです。

トレタO/Xではモバイルオーダー上から会計ができるオンライン決済と、内製のモバイルPOSであるO/X-POSでの対面決済が行えるようになっています。 とはいえ、多くの飲食店には既にPOSレジが入っているケースが大半で、キャッシュドロワー付きの筐体を導入している場合は多額の初期費用をかけているため、原価償却もありPOSレジを入れ替えるという判断はとても難しいです。

そのためトレタO/Xの導入を検討していただいている飲食店様からは、既に利用しているPOSレジと連携してくれないか、という声をたくさんいただいておりました。 そこで外部POSとの連携開発を行い、第1弾としてNECモバイルPOSとの連携のリリースに至ったわけです。

データ連携のアプローチ

POSレジではお会計をするものなので、伝票データを持っています。伝票データは請求金額だけではなくもちろん注文内容も含んでおり、注文を入れるための商品マスター情報をPOSレジは持っています。 つまり、モバイルオーダーとしてPOSレジと連携するということは、データのマスター情報を外部POSレジ側に委ねることを意味します。 そこで、トレタO/XとPOSレジ間での連携のアプローチは2つ考えられます。

1.モバイルオーダーで受けた注文データ等を随時POS側に送る

このアプローチは既存のシステムの構成を保ったまま、連携部分を追加しやすいというメリットがありますが、デメリットはやはり分散トランザクションとなってしまう点です。注文データなのでデータロスやタイムラグは業務要件においてクリティカルな問題となり許容できるものではありません。

2.モバイルオーダー側は注文データ等を保持せず、POSレジ側のAPIにに注文を送る

1のアプローチが非機能要件的に難しかったため、今回はこちらの方式を取りました。店舗が利用しているPOSが内製のOX-POSか、外部POSかで注文の送り先を切り分ます。

マイクロサービスの差し替え

2のアプローチをとると、トレタO/Xのアーキテクチャは以下の図のようになります。緑の部分がもともとのトレタO/Xのマイクロサービス群です。内製POSを使う場合と外部POSを使う場合で利用するマイクロサービス群は大きく分かれます。 共通で利用するのはモバイルオーダーに表示するためのメニュー管理システムと、管理システム用のアカウントの認証・認可システムです。 そして、外部POSを利用する場合は注文システムやオンライン決済システムなど今までコアなデータを扱っていたシステム群は切り離されます。

これほどダイナミックなマイクロサービスの繋ぎ合わせはマイクロサービスで当初設計した時には想定していませんでしたが、実際にこれが行えたのはマイクロサービスである利点かと思っています。ドメインごとに疎結合にしていたおかげで、必要なシステムだけを取捨選択することができています。

実際に、外部POS連携を企画してからこの形に設計し、実装は約3ヶ月で行うことができました。修正箇所がほぼフロントエンド側だけで済んだ点が大きいです。

ここでとつぜんPRですが、フロントエンド内でいかに分岐してそれぞれのパターンと整合性をとったか、という話は来週行われるTORETA TECH UPDATE のイベントでテックリードを務めた奥野さんから詳細に語っていただきます!

toreta.connpass.com

この先の発展

今回はNECモバイルPOS連携の初回リリースを目指したので、もちろん行き届いていない課題点はいくつかあります。 特に商品マスターがトレタO/X用のメニュー管理システム内と、外部POSシステムが持っている商品マスターで二重管理となってしまっています。

トレタO/Xのコンセプトは商品の魅力を最大限に表現して注文体験を向上させることを大きな価値としているため、POSレジ側が持っている商品マスターのデータ構造だけでは足りずに多くの付加情報を持たせられる必要があります。そのため商品マスターをどちらかのみにすることは難しいため、それぞれのマスターデータをいかにスムーズに同期させるかが次の課題となっています。

また、外部POS連携第1弾と前段で書いた通り、他の外部POSとも今後積極的に繋げていく予定です。これをやるにはフロントエンド側で切り替えしていくには限界がくるため、POS連携用のシステムが必要になってきます。各POSレジが提供しているAPIやデータ構造をいかに抽象化していくか、こちらも次の大きな挑戦です。

次のプレスリリースが出せたタイミングで、また振り返って開発の内部を紹介をしようと思いますので、乞うご期待ください。

奥野さんと社員のリファクタリング部屋 -API分割とその前に

「奥野さんと社員のリファクタリング部屋」は、リファクタリングに励むトレタの社員と技術顧問の奥野さん ( @okunokentaro ) の間で実際に行われた会話を切り取った開発現場実録コンテンツです。

技術顧問: 奥野さん
三度の飯よりリファクタリングが好き
今回の質問者: 武市さん
トレタ在籍2年。沖縄在住のフロントエンジニア

PR

こちらに登場している2人が登壇するイベント・TORETA TECH UDATEが2024/08/28に開催予定! リファクタリングやリアーキテクトなど、サービスを提供させながらプロダクトの新陳代謝をいかにして行なってきたかを開発現場の実例と合わせて紹介します! toreta.connpass.com


今回の質問💬

現在BFFの実装で、各ページごとは基本的に一つのAPIにリクエストをしています。ただ、このAPI使い回されている場合もあります。

例えば、「商品取得API」というAPIを作成して、それは商品詳細を表示するために使われているページで使われているAPIです。 一方で、商品を編集するページからも「商品取得API」を呼び出しています。 これ自体は問題ないのですが、「商品取得API」というのは商品詳細を表示するページに必要な情報をBFF(API)でまとめて取得している点に違和感を私は感じています。

例えば、「商品取得API」が商品自体の情報を返すという機能としているにも関わらず、付随する情報、例えば価格の情報やタグの情報なども同じAPIで取得しています。 これはそれぞれの情報に対応する専用のAPI、例えば注文取得APIと注文履歴API、2回リクエストしたほうが再利用性が高いのではと思っています。

今後の方針としては、各APIは単一の責務を担当するというルールで定めようと検討しているのですが、奥野さんのご意見をいただきたいです。

誰のためのリファクタリング?

奥野 この話題はずっと議論されている鉄板中の鉄板の話題だと思うんですよ。 一回の通信でどの様にに返すべきか、結局は何を目指したいかによると思います。通信(ハンドシェイク)が増えれば増えるほど、当然レスポンスは遅くなっていきます。

BFFというポジションとして、直接別にデータベースとやり取りをしているわけではなく、別の外部のRESTfulなAPIやGraphQLなどから取得してくるということは、APIを分ければ分けるほどレスポンスは遅くなっていきます。 なので何を指標に置くかによると思っていて、分けることによって段階的な画面のレンダリングができるから、エンドユーザーにとって高速な表示が可能であるなのか、分けることで開発者が管理しやすいなのかによっても変わってきますね。 武市さんがこういうアーキテクチャをとろうという判断に、「誰のために」が欠けている気がします。

誰に対してプロダクトを作っているのかは、プロダクトを使ってくれるお客さんがいてこそだから、お客さんよりも自分たちの開発の利便性を優先するっていう判断は自分は怪しいなと思っています。 エンドユーザーに高速に提供するためにはこうなんだけど、トレードオフがあってやむを得ずここは分けないとツライ、みたいなジレンマはあると思います。そこを考えずに、まず開発のリファクタリングありきであったり、コードが細分化されている方がテストしやすいとか開発しやすい、というのはお客さんの方見てないな、と思ってしまいます。

武市 おっしゃるとおりで、トレタではVercelを使ってるのでキャッシュされるから、そこまでフォーマンス落ちないだろうみたいな、結構安直な考えだったところはありました。

奥野 キャッシュがあったとしても、情報ごとにキャッシュの鮮度というものがあって、頻繁に更新されないって分かってるんだったらキャッシュは有効でもいいけど、頻繁に更新される部分であったら、そもそもキャッシュは有効な手段ではない、となってくる。 例えば、画面上のレンダリングを分割して出したいとか、分割して一部の情報は一回取得すれば十分とか、ここの部分の情報は頻繁に変わるから頻繁にフェッチさせる必要がある、みたいに使いまわせる部分と、都度取得しに行かないといけない部分というのはあります。 モバイルオーダーアプリで言うと、タブとかあまり頻繁に変わらない部分もあるので一度取得したら十分だけど、在庫の情報は頻繁に変わるから都度取得しないと、売り切れなのに画面では販売中になっていたりしたら問題になてしまう。

どういった切り口でもいいですが、その開発はエンドユーザーのためにやってるのか、開発者のために行っているのか、運用コスト改善のためにやっているのか、とにかく指標を定めないまま、考えているような印象を受けたので、そこをしっかりと考えてから話を持ち出したほうがいいと思います。

武市 なるほど。ちょっと自己中的な考えだったことに気がつきました。開発者の目線しか見れていなかったです。

リファクタリングの目的を意識する

奥野 この時間はどうリファクタリングしていくかっという部分で議論してはいるけど、リファクタリングで開発生産性が上がることを目的にしてはいけないんですよ。

開発生産性が上がることが目的になるのではなくて、開発生産性が上がることによってエンドユーザーに届けることができるバグ修正だったり、機能追加が頻繁になることが目的だから、開発生産性を上げようではなくて、開発生産性を上げたことでエンドユーザーに価値を届けようなんですよ。

だからそこをリファクタリングを目的にするとかなり間違っているので、今回はリファクタリングを目的にする以前に、今回はAPIの分割を目的にしてしまっているから、しっかりとゴールを見据えないとなっという危うさは感じました。

武市 よくありがちな、手段が目的になってしまっているやつですね。

奥野 何のためにリファクタリングをしているのか、何のためにAPIをまとめる、あるいは分割するをやろうとしているのか、というその先にあるお客さんに与える価値っていうのを考えるというと思います。 そこを考えた上で分割すべきAPIを検討するだったり、統合して一個のAPIでまとめて返した方がいいのであればそれを検討するといいと思います。

武市 はい、ありがとうございます。視点がずれていたところを気づきをいただき、ありがとうございました!

コラム: REST API・GraphQL・BFFの変遷

今回は質問の答えには辿り着けませんでしたが、あらためてBFFやREST API・GraphQLなどが生まれてきた背景や目的を振り返ってみましょう。

2000年初期のWeb開発ではPHPやRubyOnRailsなど、サーバーからHTMLを返してレンダリングする方法が主流でした。RubyOnRailsではMVCモデルという開発パターンがとられており、ControllerがModelを基にHTMLであるViewを返す仕組みとなっていました。

そこからスマートフォンが流行りだし、アプリ開発が盛んになりました。アプリ開発の場合はアプリとAPIが分離されるため、アプリエンジニアはクライアント開発を行い、サーバーサイドエンジニアはAPI開発を行う分業化がされるようになりました。Webとアプリの両対応するケースも増えたので、Web側もアプリと同様の構成でAPIを呼び出すJavascript製フレームワークが登場しました。APIはマルチクライアントに対応したり外部に公開するケースも増えていったため、特定の画面に依存したAPIではなく汎用的に使えるRESTとしてリソースに準拠したAPI形式になっていきました。

APIがRESTになってくると、今度はクライアント側で必要な項目の足し引きが問題になっていきます。一覧画面では最低限の項目で十分ですが、詳細画面ではすべての項目および関連するリソースも必要となってきます。一つのAPIでそれらを包括して関連するリソースとそのネストしたリソースまで返却するようになると、データ量が多くレスポンス速度も下がってしまいます。一方で各画面に必要な項目だけを返すAPIを画面ごとに作っていくと開発量は増大していきます。そこで現れたのがGraphQLです。呼び出し側がクエリで必要な項目を指定することで最適なレスポンスをサーバー側の改修を必要とせず取得することができるようになりました。

一方、サーバー側はモノリシックな構成からマイクロサービスとしてデータベースやサーバーをドメインごとに分割する流れがでてきました。サーバーが分割されると必要なデータを取得するために複数サーバーへリクエストを必要とする場面がでてきます。そこで、データ取得や画面用にデータ加工をするサーバーとしてBFF(BackendForFrontoend)パターンが登場しました。クライアント側からはビジネスロジックを分離して表示処理に専念できるようになるため、フロントエンドの進歩により複雑化したこともあいまって必要性が高まりました。 BFFを入れることで通信は一回増えますが、HeadlessCMSなど外部APIも豊富になってきたため、クレデンシャル情報を持った処理を行うために中間サーバーを設けることも一般的になりました。

さらに現在の2024年においては、さらにBFFの在り方は変わりReact/Next.jsではSSR(Server-seide Rendering)やRSC(React Server Rendering)などサーバー側でレンダリングを行う流れが活発になっています。これは初期のPHPなどサーバーでHTMLを返していた頃と体系は似ており、技術トレンドが一巡したのかもしれません。

© Toreta, Inc.

Powered by Hatena Blog