
はじめに
こんにちは、出前館の中川です。
2026年5月30日に開催された「JJUG CCC 2026 Spring」にて
「出前館のメニュー登録・更新用APIをSpring Boot + Kafkaで実現したお話」というタイトルで登壇させていただきました。
イベント全体の様子や当日の雰囲気については、すでに公開しているnoteでも触れているので、そちらもあわせてご覧ください。
このブログでは、イベントレポートというよりは登壇者個人の振り返りとして、
- 「なぜこのテーマで話そうと思ったのか」
- 「登壇を通じて何を得たのか」
- 「発表の中でも駆け足になってしまった今後の話」
を中心に振り返っていきます。
登壇時のスライドはこちらです。先にスライドの方に目を通していただくと、このあとの内容がより伝わりやすいかと思います。
(こんなお菓子を配布していた者です!)
登壇の動機、背景
私は2025年7月に出前館に入社し、メニュー連携をはじめとした商品領域の開発に携わっています。
入社して早々に着手したのが、今回発表したメニュー連携の機能でした。
実装に入る前に「そもそもどう設計するか」でしっかり悩んだ機能で、 「バッチで定期的に拾って処理する」か「Kafka + Subscriberで受付と処理を分離する」か比較検討を重ねて 明確な理由を持ってKafka + Subscriber構成に決めました。
この意思決定の流れは、なんとなくではなくきちんと考えて整理した分、社外の方にも共有する価値があるのではないかと思ったのが、登壇を決めた1番の理由です。
加えて、Kafkaは歴史のある技術で、多くの現場ですでにインフラとして組み込まれていることかと思います。
そのため、最近は既存に対してトピックを追加するなどの関わりはあれど、構築部分から携わる機会は意外と少ないのではと思いました。
だからこそ、実際にイチから設計・実装した際の実務に即した話には需要があるのではと思ったのも、登壇した理由のひとつです。
登壇を通して得られたもの
1番大きかったのは、バッチ方式とKafka + Subscriber方式のどちらを選ぶかという場面で、
- 自分たちが何を優先してどうトレードオフしたのか
- 何を大事にして設計判断をしていたのか
- これらを資料に落とし込む過程で改めて見つめ直せたことです。
頭の中では分かっていたつもりの判断基準を、他人に伝わる言葉として言語化し直すことで、自分の中でも「なぜこの設計にしたのか」がより解像度高く再認識できたように思います。
一方で反省点もあって、かなり時間ギリギリまで話してしまい、最後の「今後のこと」の部分がだいぶ駆け足になってしまいました。
手元のタイマー表示を見ながら「まだ余裕あるな」と思っていたのですが、気づけばそんなに余裕はなく…
このあたりの時間感覚のズレは、次に登壇する機会があれば改善したいポイントです。
登壇自体の経験としても、大人数の前で技術的な意思決定の背景を筋道立てて話す、という機会は中々ないので、伝え方・資料構成の面で純粋に良い訓練になったと感じています。
登壇後のことと今後のこと
今回の登壇で扱ったメニュー連携APIは登壇当時には、まだシステムリリースはしていませんでした。
登壇後、無事にシステムリリースをし、出前館が加盟店向けに提供しているAPI群を紹介しているDeveloper Siteでもドキュメントを公開しています。
「メニューインテグレーション」のページでは、メニューパターンの登録からメニューパターンツリーの更新・照会、店舗への紐付けまで、一連のAPIの仕様や連携の流れを確認いただけます。
メニュー連携にご興味を持っていただいた方は、ぜひ覗いてみてください。
さて、発表の最後は時間が押してしまい駆け足での紹介になってしまったので、今後のことをこちらで補足いたします。
実は、現状だとメニューパターンツリー登録・更新の利用頻度自体は11リクエスト/日とまだそこまで多くありません。
この11件だけの話となってしまいますが、処理時間は下記の通りとなっており
| # | 開始時刻 | 終了時刻 | 処理時間(秒) |
|---|---|---|---|
| 1 | 19:30:37.444925 | 19:30:52.754173 | 15.31 |
| 2 | 19:30:37.592011 | 19:30:48.530555 | 10.94 |
| 3 | 19:30:07.521562 | 19:30:18.581967 | 11.06 |
| 4 | 19:30:07.994331 | 19:30:17.414321 | 9.42 |
| 5 | 11:03:41.767690 | 11:03:56.025432 | 14.26 |
| 6 | 10:59:25.380878 | 10:59:37.091206 | 11.71 |
| 7 | 10:45:34.792378 | 10:45:45.766664 | 10.97 |
| 8 | 10:45:00.635888 | 10:45:12.492194 | 11.86 |
| 9 | 10:44:32.321518 | 10:44:43.514221 | 11.19 |
| 10 | 10:44:20.960571 | 10:44:33.099377 | 12.14 |
| 11 | 10:44:12.287051 | 10:44:32.879701 | 20.59 |
- AVG: 約12.68秒
- MIN: 9.42秒
- MAX: 20.59秒
最初の1件がAVGよりも約8秒以上遅い、つまり商品画像を新規で登録しているため多少時間を要しています。
しかし、それ以降のメニューパターンツリー登録・更新では一度登録された画像を使い回しているため、10数秒程度で更新が完了していることから
実際に同じ画像であれば登録結果を使い回す仕組みの効果が出ていることが分かります。
今後利用が増えていく中でさらに狙い通りのスケーラビリティを発揮できているかどうか効果が見えてくる部分だと思っているので、 きちんとモニタリングし続けられるようにする、というのが今のフェーズです。
そのために今まさに力を入れているのが可視化まわりです。
Consumer Lagや処理時間の分布、画像の使い回し状況といった「体感」で語りがちな部分を、ダッシュボードとして数値で見える化する作業を進めています。
これはKafka + Subscriberの構成そのものの良さを、数値でちゃんと示したいという狙いが強いです。
受付処理を軽く保ったまま重い処理を裏で並列に回せる設計になっているので、負荷が増えてもConsumer側をスケールさせれば吸収できるはず、というのがこのアーキテクチャの一番の強みだと思っています。
画像登録まわりも、同じ画像であれば登録結果を使い回す仕組みを入れているので、 実際にどれくらい重複ダウンロードを削減できているのか、キャッシュヒット率という形で可視化できれば、設計の狙いがそのまま数字として裏付けられるはずです。
こうした「仕組みとしての強さ」を、感覚ではなくダッシュボード上の数値としてきちんと語れるようにするところまでを含めて 次に登壇する機会があればアップデートとしてお話できたらと思っています。
おわりに
準備段階では資料作りに苦労した部分も多かったのですが、当日は多くの方に聞いていただけて、登壇して本当に良かったと感じています。
時間配分は次回への反省点として持ち帰りつつ、また機会があればぜひ登壇したいと思っています。
改めて、セッションを聞いてくださったみなさま、運営に携わってくださったJJUG実行委員のみなさま、ありがとうございました。
出前館としても継続してJavaコミュニティに関わっていきたいと思っていますので、今後も会場やオンラインでお見かけした際はお気軽に声をかけていただけると嬉しいです。
興味を持っていただいた方はイベントページやnoteも含めてぜひご覧ください。