
LaravelのAPI連携、ダッシュボードのLCPが3.2秒から2.1秒に落ちるまで
最初は当然のようにRESTで組んだ。ユーザー用、投稿用、通知用、統計用のエンドポイントを用意し、フロントエンドから順番に呼び出す。設計としては素直で、Laravelの標準機能にもよく馴染む。ところが、リクエストは4回になった。モバイル回線で開くと、画面の一部が表示されてから次のデータを待つ時間が長い。体感で明白な「もたつき」が残った。
Search ConsoleとLighthouseの双方で計測すると、モバイルのLargest Contentful Paintは3.2秒、初回表示の完了率は58%だった。これは仮説の段階ではなく、ユーザーの離脱という確定したファクトとして目の前に突きつけられていた。PageSpeed Insightsでも「初回サーバー応答時間を短縮する」という警告が並んでいた。
そこで、次の一手としてGraphQLを部分導入した。ダッシュボードに必要なデータをひとつのクエリにまとめ、初回表示のラウンドトリップを4回から1回に圧縮する。結果、LCPは約2.1秒まで改善した。
ただし、この結果だけを見て「GraphQLのほうがRESTより優れている」と結論づけるのは早い。実際には、RESTを捨ててGraphQLに全面移行したわけではない。CRUD中心のAPIや、CDNキャッシュを使いたい公開データはRESTのまま残し、画面ごとに複数のデータを組み合わせる箇所だけGraphQLに寄せた。
この記事では、LaravelでRESTとGraphQLを実運用した経験をもとに、両者の違いを比較する。特に個人開発では、機能の多さよりも「どこまで自分ひとりで運用を続けられるか」が重要になる。その前提から、LaravelのAPI連携でどちらを選ぶべきかを考えていく。
Laravel標準機能で完結するREST APIの堅実な設計
LaravelでRESTを組む最大の利点は、外部パッケージを追加せず、標準機能を中心に設計できることだ。routes/api.php、コントローラー、APIリソース。この3つを軸にすれば、入力を受け取り、データを取得し、外部に返すJSONを整形する責務を分けられる。
もちろん、認証やレート制限、バリデーションまで含めれば考えることは増える。それでも、Laravelのルーティング、ミドルウェア、フォームリクエスト、Eloquent、APIリソースといった既存の仕組みで大半を組み立てられる。個人開発でLaravel REST APIを設計するとき、この「知っている道具だけで最後まで進める」感覚はかなり大きい。
リソース指向のAPI設計は、Eloquentのテーブル構造と相性がいい
LaravelのEloquentは、データベースのテーブルとモデルを自然につなげてくれる。ユーザー、投稿、コメント、通知といったリソースをモデルとして扱い、それぞれに一覧、詳細、作成、更新、削除の操作を割り当てる。テーブルとモデルの関係が比較的わかりやすいため、APIのURLにもその構造を反映しやすい。
APIリソースを間に挟めば、「テーブルのカラム」と「APIで返すフィールド」を分離できる。モデルの中身をそのままJSONに変換するのではなく、toArrayメソッドで必要な項目だけを明示する。内部用の識別子や権限情報を隠したい場合も、表示ポリシーをコントローラーから切り離せる。
この分離を怠ると、最初は速くても後から困る。モデルにカラムを追加しただけでAPIのレスポンスが変わったり、管理画面では必要な情報が一般ユーザー向けのAPIにも混ざったりするからだ。個人開発では、同じ人間がモデルもフロントエンドも触る。だからこそ、頭の中だけで管理せず、返すフィールドをコード上で明示しておいたほうがいい。
僕の場合、CRUD中心のAPIはおよそ10本前後動いている。リソースの粒度がそのままURLに現れるシンプルさは、運用フェーズに入ってからの「エンドポイントを忘れる」という認知コストを下げてくれる。
- 一覧取得は、一覧として必要な項目に絞る
- 詳細取得は、詳細画面に必要な関連データを追加する
- 作成と更新では、フォームリクエストで入力ルールを分ける
- 削除や状態変更は、HTTPメソッドとURLだけで意味が伝わる形にする
- レスポンスの形式はAPIリソースでそろえる
ここまでの設計なら、フロントエンドがVue.jsでもReactでも、APIの仕様を読み解く負担は大きくならない。APIドキュメントを見ながら、必要なエンドポイントを呼び出せばいい。
一方で、RESTは画面の要求が複雑になった瞬間に、エンドポイントの数が増えやすい。ダッシュボードのためにユーザー情報、投稿情報、通知情報、統計情報を個別に取得するなら、フロントエンド側で複数のリクエストを管理することになる。画面が増えるたびに「この画面専用のエンドポイント」を追加すると、いつの間にかAPIの責務が曖昧になる。
RESTの欠点は、設計が悪いとすぐに現れる。ただし、逆にいえば、問題の位置を追いやすい。どのURLが遅いのか、どのレスポンスが大きいのか、どのSQLが重いのかを、HTTPリクエスト単位で確認できる。この追跡のしやすさは、個人開発の現場では機能のひとつだと思っている。
キャッシュ制御と条件付きリクエストを扱いやすい
RESTはHTTPのセマンティクスをそのまま利用できる。GETにはキャッシュヘッダーを設定し、ETagを使って条件付きリクエストを行う。PUTやDELETEでは冪等性を意識する。どれも派手な仕組みではないが、CDNやリバースプロキシを組み合わせると効いてくる。
Laravel側でも、頻繁に変わらないデータならCache::rememberでデータベースへの問い合わせを減らせる。さらに、レスポンスのCache-Controlを適切に設定すれば、同じデータをアプリケーションサーバーまで取りに来る回数も抑えられる。
RESTの最大の強みは、HTTPという枯れたインフラの上に成り立っていること。キャッシュも認証も、まずヘッダーを見て考えればいい。
サービス運用を続けて痛感するのは、「枯れた仕様」は最良のキャッシュ戦略になることだ。新しい仕組みを学ぶより、既存仕様の組み合わせで解決できたほうが、ユーザーの痛みに早く届く。
もちろん、RESTなら自動的に高速になるわけではない。毎回重いJOINを実行していたり、一覧で不要なカラムまで返していたりすれば、URLが分かれていても遅い。ページネーション、取得項目の制限、インデックス、Eager Loadingといった基本的な改善は必要だ。
それでも、RESTではキャッシュとデータ取得の境界が見えやすい。公開記事の一覧は長めにキャッシュし、ログインユーザーの通知は短くする。ユーザーごとに内容が変わるレスポンスは、共有キャッシュに載せない。このような判断を、HTTPのURLとヘッダーを見ながら組み立てられるのがRESTの堅実さだ。
Lighthouseが切り開くGraphQLの選択肢
一方、フロントエンドの要求が複雑になってくると、RESTの「必要なリソースごとにリクエストを投げる」構造が負担になる。
管理画面のように、ひとつの画面で複数のデータを組み合わせるケースでは、ユーザー、投稿、通知、統計を別々に呼ぶ必要がある。リクエストを並列に投げても、通信処理、認証、サーバー側のクエリ、レスポンスの解析はそれぞれ発生する。モバイル環境では、サーバーの処理時間だけでなく、通信回数そのものが初回表示に響く。
ここで選択肢になるのがGraphQLだ。Laravel向けの実装パッケージとして、僕が使ったのはLighthouseだった。
オーバーフェッチとアンダーフェッチを同時に扱える
RESTでは、リソース単位でレスポンスが決まることが多い。画面にユーザー名だけが必要なのに、プロフィール、権限、登録情報まで返ってくることがある。これはオーバーフェッチだ。
逆に、一覧画面にユーザー名、最新の投稿、未読通知数が必要なのに、ユーザーAPIだけでは投稿と通知を取れない場合もある。追加のエンドポイントを呼び出すか、画面専用の集約APIを作る必要がある。こちらはアンダーフェッチとして扱われる問題だ。
GraphQLでは、クライアントが必要なフィールドをクエリで指定できる。ユーザー名と未読通知数だけが必要なら、その項目を要求する。投稿一覧ではタイトルと公開日時だけを取得し、詳細画面では本文や関連情報を追加する。レスポンスの形を画面側の要求に近づけられるため、不要なデータを流しにくい。
実務では、ペイロードを30〜50%ほど小さくできるケースがある。ただし、これはGraphQLを導入しただけで自動的に実現するものではない。クエリの設計が粗ければ、必要以上の関連データを取得してしまうし、サーバー側のSQLが増えればネットワーク上の節約がそのまま性能改善にはつながらない。
Lighthouseでは、スキーマ定義言語を使って型とフィールドを定義する。対応するリゾルバーやEloquentモデルとの接続をディレクティブで表現できるため、コントローラーを画面ごとに増やしていく設計より、データの構造を一箇所で把握しやすい。
ただし、ここにも前提がある。スキーマを適当に書けば、APIの契約が明確になるどころか、複雑な依存関係をひとつの入口に押し込めるだけになる。GraphQLでは、エンドポイントの数が少ないことと、システム全体が単純であることは同じではない。
フロントエンドのVue.jsやReactと自然に組み合わせられる
GraphQLの「クライアントがデータの形を決める」という性質は、Vue.jsやReactのようなコンポーネント指向のフロントエンドと相性がいい。
コンポーネントごとに必要なデータが違う場合、RESTではエンドポイントを増やすか、既存のレスポンスを流用することになる。後者を選ぶと、画面には不要なフィールドが増え、前者を選ぶと画面専用のAPIが増える。
GraphQLでは、コンポーネント側の要求をクエリとして表現できる。Apollo Clientやurqlを組み合わせれば、データ取得、キャッシュ、ローディング状態、エラー処理をひとつの層で管理しやすい。VuexやReduxに取得済みデータを重ねて持つ構成で感じていた、同じデータを別のストアにも保持する重複も減らせる。
ここで大事なのは、GraphQLがフロントエンドの都合を無条件に優先する仕組みではないことだ。クライアントが自由にクエリを書けるということは、サーバー側が想定外の組み合わせを受け取る可能性もある。認証済みユーザーだけが見られるフィールド、管理者だけが取得できるフィールド、公開してよい関連情報を、スキーマと認可の両方で管理しなければならない。
データ構造が「画面起点」に変わる瞬間、GraphQLはRESTの代替ではなく、かなり魅力的な選択肢に見えてくる。
ただし、この「上位互換感」は運用フェーズに乗せると揺らぐ。データ取得の自由度が上がるほど、クエリの深さ、関連の数、権限チェック、キャッシュの扱いまで設計対象になるからだ。
N+1問題とクエリ最適化――GraphQLの落とし穴
ここで声を大にして言っておきたいことがある。GraphQLは常にRESTより高速、という主張を鵜呑みにしないことだ。
GraphQLは通信回数を減らせるが、データベースへの問い合わせ回数まで自動的に減らしてくれるわけではない。むしろ、ひとつのクエリに多くの関連データを詰め込めるため、設計を誤ると、サーバー側で大量のSQLを発行する。
Eager Loadingを支えるLighthouseのディレクティブ
Lighthouseには、Eloquentの関連を扱うためのディレクティブが用意されている。@belongsTo、@hasMany、@withなどをスキーマに書き添えることで、関連データの取得方法を定義できる。
たとえば、ユーザー100件に対して、それぞれの投稿を個別に取得する設計では、ユーザー一覧を取得したあと、ユーザーごとに投稿取得のクエリが発生する。いわゆるN+1問題だ。@hasManyやEager Loadingを適切に使えば、関連データをまとめて取得し、クエリの発行回数を抑えられる。
ただし、ディレクティブを付ければすべて解決するわけではない。投稿の投稿者、その投稿者の通知、通知に紐づく別のリソースまで一度にたどると、取得するデータ量も、認可の確認回数も膨らむ。クエリの形が見えにくいぶん、RESTより早い段階で制限を設けたほうがいい。
特に確認したいのは、次のような点だ。
- 一覧で取得する関連データに上限があるか
- ページネーションが関連ごとに機能しているか
- 同じ関連を複数のフィールドから重複して呼んでいないか
- 認証や認可の処理が各フィールドで過剰に走っていないか
- クエリの深さと複雑さを環境ごとに制御できているか
- ログからSQLの発行数とレスポンスタイムを追跡できるか
GraphQLでは、フロントエンド側のクエリを見ただけでサーバーの負荷を判断しにくいことがある。見た目はひとつのリクエストでも、内部では多くの関連を順番に解決しているかもしれない。リゾルバーやEloquentのログを確認し、データベースの実際の動きを見る必要がある。
失敗談――8秒レスポンスの原因は自作クエリだった
僕の運営するサービスで、Lighthouse導入直後にやらかした失敗をひとつ記録しておく。
計測なしに運用へ乗せたクエリが、Query complexity: 1000を超える巨大クエリになり、レスポンスタイムが8秒を記録した。原因は、ネスト5階層のフィールドを許可したことだった。@withを付けず、Eloquentに関連データの解決を任せていた。
画面に必要なデータをひとつのクエリで取得できることに気を取られ、サーバー側でどのようなSQLが発生するかを確認していなかった。RESTならエンドポイントごとに遅さが見えていたはずだが、GraphQLではひとつの入口の裏側に処理が隠れる。その違いを理解していなかった。
以来、運用フローにふたつの原則を入れた。まず、maxDepthを必ず設定する。クエリがどこまでも関連をたどれる状態にしない。次に、maxComplexityを設け、事前に計測できるサンドボックスを通す。画面に必要だからという理由だけで、深いネストを許可しない。
開発中は、便利なクエリを一度書くと、そのまま使い続けたくなる。しかし、ユーザー数やデータ量が変われば、同じクエリでも処理時間は変わる。開発用データでは問題なくても、本番で投稿数や通知数が増えたときに突然限界が来る。
GraphQLを採用するなら、次のような運用も早めに決めておきたい。
1. 一覧系のフィールドにはページネーションを前提にする
全件取得を許可すると、レスポンスの大きさだけでなく、SQLとメモリの使用量も予測しづらくなる。
2. クエリの深さと複雑さに上限を設ける
上限は一度決めて終わりではなく、実際の画面要件とログを見ながら調整する。
3. 開発環境でSQLとレスポンスを計測する
クエリがひとつにまとまったことではなく、サーバー内の処理が改善したかを見る。
4. 重いフィールドを分離する
統計計算や全文検索など、単純な関連取得とは性質が違う処理を、同じクエリに詰め込みすぎない。
5. 認証と認可の境界をスキーマに反映する
取得できるデータの形だけでなく、誰がどこまで取得できるかを明確にする。
N+1問題は、Lighthouseのようなパッケージを導入したあとも、設計で潰すしかない領域だ。自動化は判断を代わりにしてくれるものではなく、正しい方針を実装しやすくするものにすぎない。仮説で判断せず、ローカルの計測ログを流してから本番へ投入する。これが、後から大きな修正をしないための近道になっている。
キャッシュとHTTPの特性――RESTが見捨てられない理由
技術選定で後回しにされがちだが、キャッシュは個人開発にとって死活問題だ。CDNを前面に置くのか、サーバーサイドでRedisを使うのか、データベースへの問い合わせをどこまで減らすのか。この差は、最終的にレスポンス速度と運用コストへ跳ね返る。
RESTはHTTPキャッシュをそのまま活用できる
RESTはリソースごとに固有のURLを持つ。そのため、レスポンスの性質に合わせてキャッシュの方針を決めやすい。
公開記事の一覧や、頻繁には変わらないカテゴリー情報であれば、Cache-Control: public, max-age=300のような指定を置いて、一定時間CDNに保持できる。CloudFrontやFastlyを前面に置く場合も、URL単位でキャッシュの状態を確認しやすい。
ログインユーザーごとに内容が変わる通知や設定情報は、共有キャッシュに載せない。必要ならLaravel側のアプリケーションキャッシュを使い、ユーザー単位でキーを分ける。公開データと個人データを同じ感覚で扱わないことが重要になる。
ETagやLast-Modifiedを使えば、データが変わっていない場合に完全なレスポンスを返さずに済む。これもRESTそのものが性能を保証するわけではないが、HTTPの仕組みを利用して段階的に改善できるという意味で、実装の見通しがいい。
GraphQLは単一エンドポイントの設計がキャッシュを難しくする
一方、GraphQLは通常、/graphqlのような単一エンドポイントでクエリを受け取る。クエリ本文はリクエストボディに含まれることが多く、URLだけを見て「どのデータのレスポンスか」を判断しにくい。
同じエンドポイントに対して、ユーザー一覧を取得するクエリも、通知だけを取得するクエリも、統計を取得するクエリも届く。クエリの内容が違う以上、同じURLだから同じレスポンスを返せるわけではない。認証ユーザーによって結果が変わるなら、なおさら共有キャッシュには慎重になる。
GraphQLでもアプリケーション内のキャッシュは使える。リゾルバーの結果をキャッシュしたり、Apollo Client側で取得済みデータを再利用したりする方法もある。ただし、RESTのHTTPキャッシュとは考え方が違う。どの層で、どのキーを使って、いつ無効化するのかを自分たちで設計しなければならない。
永続クエリは強力だが、運用負荷が増える
GraphQLには、永続クエリやハッシュ化したクエリを使い、GETリクエストに寄せる方法がある。クエリをあらかじめ登録しておけば、サーバー側で許可したクエリだけを実行できる。キャッシュやセキュリティの面でも有効な場面がある。
ただし、クエリをビルド時に登録する運用が追加される。フロントエンドのビルドスクリプト、サーバー側の登録情報、デプロイの順番まで管理対象になる。クエリを変更したのに登録を更新していない、古いハッシュが残っている、といった別の問題も起こりうる。
1人で運用する規模では、このコストが小さく見えるようでいて積み上がる。GraphQLの柔軟性を活かすために、デプロイ手順や監視を複雑にしてしまうなら、本来の目的から外れている可能性がある。
RESTのエンドポイントはphp artisan route:cacheで最適化できる。CDNやリバースプロキシの設定も、URLとHTTPメソッドを見ながら組み立てられる。LighthouseとCDN、認証、永続クエリを連携させるより、少ないコードで目的を達成できるケースは多い。
個人開発の速度は、実装の速さだけではなく、運用が回るかどうかで決まる。
個人開発の「次の一手」を最大化する技術選定
ここまでの話を踏まえて、僕自身は次のような基準でRESTかGraphQLかを選んでいる。
| 判断基準 | RESTを選ぶケース | GraphQLを選ぶケース |
|---|---|---|
| 画面要件 | 単純なCRUD中心、一覧と詳細の典型構成 | 複数のデータを1画面で合成する |
| データの関係 | リソース同士の境界が比較的明確 | 関連データを画面ごとに異なる形で取得する |
| チーム規模 | 個人開発や小規模チームで完結する | フロントエンドとバックエンドが分業している |
| キャッシュ戦略 | CDNを前面に置き、HTTPキャッシュを活用したい | アプリケーション内のキャッシュを許容できる |
| 学習・運用コスト | Laravel標準機能を中心に進めたい | スキーマ、ディレクティブ、クエリ制限を管理できる |
| API契約の変更頻度 | エンドポイントが安定し、変化が少ない | 画面の変更に合わせて取得項目が頻繁に変わる |
| 性能上の課題 | サーバー処理、SQL、キャッシュが主なボトルネック | 通信回数やレスポンスの過剰取得が主なボトルネック |
この表でGraphQLに当てはまる項目が多くても、すぐに全面移行する必要はない。API連携の方式は、サービス全体でひとつに統一しなければならないものではないからだ。
公開コンテンツの取得はREST、管理画面の集約データだけGraphQL。ファイルアップロードやWebhookはREST、複雑な読み取りだけGraphQL。このように、読み取りと書き込み、公開データと認証データを分けて考えると、導入のリスクを抑えやすい。
迷ったらRESTから始める理由
仮説段階の機能を最初からGraphQLで組むことを、僕自身はあまりおすすめしていない。理由はシンプルで、プロダクトがユーザーに届く前に、インフラの学習コストを支払うことになるからだ。
検証したいのは、機能が使われるかどうかであって、GraphQLの動作ではない。まずRESTで動くMVPを出す。ユーザーの反応を見て、APIのもたつきが離脱率に効いているという仮説が取れたら、そこでGraphQL導入を検討する。この順番のほうが、個人開発の時間を守りやすい。
RESTで始める場合も、後から変更しやすいように最低限の境界は作っておく。コントローラーにすべての処理を詰め込まず、APIリソースでレスポンスを整え、入力バリデーションを分ける。モデルの関連をそのまま返さず、画面ごとに必要なデータを意識する。
この準備をしておけば、後からGraphQLを追加するときも、既存のドメインロジックをすべて書き直さずに済む。GraphQLはRESTの完全な置き換えではなく、既存のデータや処理に別の取得口をつくる選択肢として導入できる。
僕のサービスでも、最初はRESTで始めた。ダッシュボードの表示が遅くなり、LCPが3.2秒という状態になった段階で、初めてLighthouseを部分導入した。結果として、初回表示のラウンドトリップを4回から1回に圧縮し、LCPを約2.1秒まで下げられた。
この改善は、GraphQLを採用したことだけで生まれたものではない。画面に必要なフィールドを洗い出し、不要なデータを削り、関連データの取得方法を見直し、通信の流れを計測した結果だ。GraphQLは、その改善を実装しやすくする道具として機能した。
「ユーザーの痛み」から逆算する設計思考
結局のところ、API設計は技術選定そのものではない。ユーザー体験のボトルネックを見つけ、それを技術で潰すための仮説検証の一部だ。
RESTを選ぶにしても、GraphQLを選ぶにしても、まず見るべきなのは次のような観測結果になる。
- 初回表示で何回のリクエストが発生しているか
- どのAPIの応答が画面表示を止めているか
- レスポンスのうち、実際に画面で使っているフィールドはどれか
- データベースのクエリ数と処理時間はどの程度か
- CDNやアプリケーションキャッシュが期待どおり機能しているか
- API変更時にフロントエンドとバックエンドのどちらへ影響が出るか
ここを見ずに、流行している方式や「モダンに見える方式」を選ぶと、問題を解決するどころか、別の管理対象を増やすことになる。
LaravelにはRESTもGraphQLも、比較的短い距離で試せる土壌がある。だからこそ、最初のバージョンはRESTで「動くもの」を出し、ユーザーの反応という客観的なフィルターを通してから、次の方式を選べばいい。
僕自身、初期のLaravelプロジェクトで、APIエンドポイントが20個並ぶ画面を作ってしまい、後からLighthouseに救われた経験がある。そのときに学んだのは、RESTが間違いだったということではない。画面の要求が変わったのに、APIの構造を変えずに継ぎ足し続けたことが問題だった。
一方で、GraphQLを入れたあとに、すべてのデータ取得をひとつの巨大なクエリへまとめるのも同じくらい危険だ。方式を変えても、設計と計測を省略できるわけではない。
RESTとGraphQLの境界を、サービスの中に引く
LaravelのAPI連携でRESTとGraphQLを比較すると、RESTは「リソースとHTTPを素直に扱う」ための方式であり、GraphQLは「画面が必要とするデータの形を柔軟に組み立てる」ための方式だと言える。
RESTの強みは、標準機能との親和性、URLのわかりやすさ、HTTPキャッシュ、障害調査のしやすさにある。個人開発であれば、まずこの強みを使い切るほうがいい。APIリソース、ページネーション、Eager Loading、キャッシュ制御を整えるだけで、かなりの問題は解決できる。
GraphQLの強みは、複数のデータを一度に取得できること、画面ごとにフィールドを選べること、フロントエンドの変更に追随しやすいことだ。ダッシュボードやSPAのように、画面が複数のリソースを横断する場合は、RESTで専用エンドポイントを増やすより扱いやすくなることがある。
ただし、GraphQLを選ぶなら、クエリの深さ、複雑さ、N+1問題、認可、キャッシュ無効化を最初から運用課題として扱う必要がある。Lighthouseのディレクティブは便利だが、便利さに任せて関連を公開すると、データベースとAPIの両方が予想外の負荷を受ける。
僕の結論は、個人開発のAPIはまずRESTから始める、というものだ。理由は、RESTのほうが常に優れているからではない。最初の仮説検証に必要な実装と運用を、最小限の構成で進めやすいからだ。
そのうえで、複数のリクエストが明確に画面表示を遅くしているなら、GraphQLを部分導入する。公開データのキャッシュや単純なCRUDはRESTに残し、複雑な読み取りだけをGraphQLに任せる。こうすれば、技術選定を宗派争いにせず、ユーザーの痛みに合わせて使い分けられる。
次に取り組みたいのは、Lighthouseの@searchディレクティブを活用した全文検索の統合と、永続クエリをApollo Clientと組み合わせたキャッシュ戦略の最適化だ。どちらも、導入すること自体を目的にはしない。実際のクエリ、レスポンスタイム、ユーザーの操作ログを計測しながら判断する。
数字で振り返り、次につなげる。このサイクルを止めないことが、Laravelと個人開発の両方を走らせる推進力になる。RESTかGraphQLかで迷ったときも、最後に見るべきなのは技術の新しさではなく、いま目の前にあるユーザーの待ち時間と、自分がその仕組みを運用し続けられるかどうかだ。
Related reading: Laravel 11のdefer関数は従来のキュー設計をどう変えるか.