記事一覧
- 障害の振り返りで「注意する」を再発防止策にしない — 防ぐ・気づく・狭める 障害の振り返りで「今後は注意する」「ダブルチェックする」と書いても、同じ障害はまた起きます。原因を「仕組みが間違いを通した」まで掘り下げ、防ぐ・早く気づく・影響を狭めるの3種類の対策に分けて、担当と期限のある変更に落とす進め方をまとめます。
- インデックスはEXPLAINで確かめる — 複合インデックスの順序と効かない書き方 「検索に使う列だからインデックスを張った」だけでは、そのインデックスが使われているかは分かりません。複合インデックスの列の順序の決め方、インデックスが効かなくなるクエリの書き方、EXPLAIN の読み方と、レビューで確かめる点を Laravel と MySQL の例でまとめます。
- Facadeを使わずDIで書くと何が変わるか — 見える依存と使ってよい場所 Laravel の Facade やヘルパーは短く書けて、テスト用の fake も揃っています。それでも UseCase では使わず、コンストラクタで依存を受け取る理由を、依存の見え方・テストの範囲・時計とトランザクションの抽象の作り方から整理し、Facade を使ってよい場所との線引きをまとめます。
- AIに渡すSpecで決めること — 作らないもの・受け入れ条件・既存の形 AIに「作ってほしいもの」だけを伝えると、書かれていない部分はAIが一般的な書き方と推測で埋めます。Specで人が先に決めておくべき、作らないもの・受け入れ条件・従う既存の形・決めていないことの4つと、Planに任せる部分との分け方をまとめます。
- CQRSを小さく始める — 検索はRepositoryでなくクエリクラスに 画面や API が増えるたびに Repository へ検索メソッドを足していくと、集約を守るためのクラスが表示の都合で膨らみます。DB もテーブルも分けず、読み取りを用途ごとのクエリクラスに切り出すところから CQRS を始める設計と、その先へ進む条件を Laravel の例でまとめます。
- Rate Limiterは何を単位に制限するか — 利用者・IP・対象と429の返し方 Laravel の throttle を既定のまま使うと、NAT の後ろの利用者がまとめて 429 になったり、ログインの総当たりを止められなかったりします。制限の目的から数える単位を決め、制限したときの応答と、Redis が使えないときの振る舞いまでを Laravel の例でまとめます。
- 切り戻すか前進修正か — リリース後の障害で迷わないための基準 リリース直後に障害が起きたとき、切り戻すか直して出し直すかで迷うと、その間も障害は続きます。切り戻しを既定にする理由、データ移行やキューのジョブで切り戻せなくなる条件、判断にかける時間をリリース前に決めておく進め方をまとめます。
- Http::fakeで外部APIの障害を再現する — タイムアウト・5xx・遅延のテスト 外部APIの呼び出しは、成功の場合しかテストされていないことがよくあります。LaravelのHttp::fakeで、タイムアウト・5xx・429・形の違う応答を再現し、リトライするか・利用者に何を返すかという設計の判断をテストに残す書き方をまとめます。
- ドメインイベントで副作用を分離する — 通知と集計を本体から外す 注文の確定に通知メール・売上の集計・キャッシュの削除を足していくと、UseCase が膨らみ、副作用の失敗や遅さが本体の失敗になります。ドメインイベントで副作用を切り離し、同期と非同期をハンドラーごとに決める設計と、イベントにしないものの見分け方を Laravel の例でまとめます。
- AIのレビュー指摘を採用するか — 妥当な指摘と過剰な指摘の見分け方 AIのコードレビューは、どの指摘ももっともらしく書かれています。全部直すと差分と防御的なコードが膨らみ、全部流すと本物の不具合を見逃します。指摘を「失敗の経路」に書き直して採否を決める方法と、レビューを何回まで回すかの止め方をまとめます。
- ページネーションはoffsetかcursorか — 件数・並び順・API互換性から決める 一覧の API を offset で作ると、件数が増えたときに深いページが遅くなり、ページをめくる間の追加や削除で行が重複したり抜けたりします。並び順を一意にする前提と、offset と cursor の使い分け、カーソルの中身と API の形の決め方を Laravel の例でまとめます。
- FormRequestとUseCaseで入力検証をどう分担するか 入力検証を FormRequest に寄せすぎると HTTP 以外の経路で漏れ、UseCase に寄せすぎると利用者に分かりやすいエラーを返せません。形式・値の不変条件・状態に依存するルールの3つに分けて置き場所を決める設計を、Laravel の例でまとめます。
- Redis・Valkeyのキャッシュが落ちたとき — DBに倒すか、機能を落とすか キャッシュの Redis や Valkey が止まると、キャッシュを読むだけの画面まで 500 になったり、応答待ちで全体が詰まったりします。タイムアウトの指定、DB に倒す値と機能を落とす値の分け方、キャッシュスタンピードへの備えを Laravel の例でまとめます。
- 集約の境界をどこで切るか — トランザクションの範囲から考える 集約を大きくしすぎると無関係な更新どうしが衝突し、小さくしすぎると守りたいルールを守れなくなります。「コミットの瞬間に一緒に正しくなければならないルール」から集約の境界を決め、外の集約は ID で参照する設計を、注文・明細・在庫の例でまとめます。
- 楽観ロックと悲観ロックの使い分け — versionカラムと衝突の見せ方 同じ行を2つの処理が読んで書き戻すと、先に書いた更新が黙って消えます。version カラムによる楽観ロック、SELECT ... FOR UPDATE による悲観ロック、条件付きの UPDATE を、衝突の頻度と利用者への見せ方から使い分ける考え方を、Laravel の例でまとめます。
- Laravelのジョブをコミット後に実行する — afterCommitとOutboxの使い分け トランザクションの中でディスパッチしたジョブやイベントは、コミットより先に動いたり、ロールバックされた処理の後続として動いたりします。Laravel の after_commit で順序をそろえる方法と、それでも残る「コミット後に依頼が消える」問題への Outbox での対処をまとめます。
- AIの生成コードをレビューする観点 — 設計との整合・影響範囲・テスト AIが書いたコードは、読みやすく、テストも通っていることが多いぶん、見た目の品質ではレビューの手がかりになりません。差分の範囲、テストと要件の対応、既存の設計との整合、失敗時の振る舞いという順で確かめる観点と、機械に移すべき確認をまとめます。
- Request IDをログとレスポンスに通す — Laravelでの実装と伝播 障害調査で1件のリクエストを追えるかどうかは、Request IDがログ・レスポンス・外部API・キューのジョブまで通っているかで決まります。Laravelのミドルウェアと Context を使った実装と、受け取ったIDを信頼してよい条件、伝播の範囲の決め方をまとめます。
- 外部APIのタイムアウトとリトライ設計 — 再送してよい失敗の見分け方 外部APIの呼び出しにタイムアウトを設定せず、失敗したら何でもリトライする設計は、障害を広げたり二重実行を起こしたりします。タイムアウトの決め方、リトライしてよい失敗といけない失敗の見分け方、指数バックオフの置き場所をLaravelの例でまとめます。
- Value Objectで「不正な値が存在しない」状態を作る — 検証を型に閉じ込める 金額や期間を int や string のまま扱うと、検証が呼び出し側に散らばり、どこで検証済みなのか分からなくなります。生成時に検証する Value Object で不正な値を作れなくする設計と、等価性・不変性の扱い、やりすぎになる境界をまとめます。
- AIにどこまで自律させるか — Spec・Plan・Human Reviewで組む開発ハーネス AIコーディングツールで重要なのは、良いプロンプトより「AIがどこまで自律的に進めてよいか」の設計です。仕様・計画・人のレビュー・AIの実装・静的解析とテストを組み合わせた開発の流れと、人に戻す条件の決め方を、個人開発での実践をもとにまとめます。
- クライアントアプリを壊さないAPI変更とリリース順序の考え方 モバイルアプリなど更新をすぐ強制できないクライアントがあるAPIでは、サーバー側の変更がそのまま障害になります。後方互換性を保つ変更の進め方、デプロイ順序、ロールバックできるかの確認ポイントを整理します。
- コードレビューで見ている9つの観点と、Must / Should / Mayの付け方 コードレビューは書き方の好みを揃える場ではなく、本番で壊れないかを確かめる場です。要件・責務・境界条件・整合性・冪等性・後方互換性など、私がレビューで確認している観点と、指摘の優先度の付け方をまとめます。
- DBとS3をまたぐ更新で、整合性の責任をどこに置くか DBのレコードとS3のファイルを一緒に更新する処理は、片方だけ成功すると不整合が残ります。呼び出し側に後始末を任せず、Repositoryなどの境界に整合性維持の責務を持たせる設計と、失敗時の順序の考え方をまとめます。
- 冪等性が必要な処理の見分け方と、Idempotency Keyによる実装 ネットワークの再送、ボタンの連打、キューのリトライで、同じ処理が2回実行されることは避けられません。冪等性が必要な処理の見分け方と、Idempotency Key・一意制約・状態遷移のチェックを使った実装、その限界をまとめます。
- Laravelのキュージョブを冪等にする — uniqueジョブに頼らない設計 Laravelのキュージョブは、リトライやタイムアウト、ワーカーの停止で同じジョブが2回実行されることがあります。ShouldBeUniqueやWithoutOverlappingで防げる範囲と防げない範囲を整理し、ジョブ自体を冪等にする設計をまとめます。
- 原因が分からない障害を、API・DB・インフラを横断して切り分ける手順 「どこが悪いか分からない」障害は、推測で直すほど長引きます。影響範囲の確定、時系列の整理、Request IDによる追跡、層ごとの切り分けという順で原因に近づく手順と、日頃から仕込んでおくべき観測の仕組みをまとめます。
- Laravelを使うが、ビジネスロジックをLaravelに支配させない Controller・Fat Model・Facade・Eloquentへの依存が積み重なると、Laravelアプリは変更に弱くなります。UseCase・Domain・Repositoryに責務を分け、フレームワークを「外側」に置く設計の考え方と、やりすぎになる境界をまとめます。
- Repository InterfaceとDTOでEloquentから業務ロジックを切り離す Eloquentのモデルをそのまま業務ロジックに渡すと、永続化の都合がロジックに漏れ出します。Repository InterfaceとDTOで境界を引く設計の具体例と、手間に見合わないケースの見分け方を解説します。
- $order->status = 'confirmed' と書かない理由 — 状態変更の責任をオブジェクトに持たせる 外からプロパティを書き換える設計では、状態遷移のルールが呼び出し側に散らばります。confirm() のような振る舞いに状態変更を閉じ込め、不変条件をオブジェクト自身に守らせる設計と、そのトレードオフを解説します。
- テストは「将来壊してはいけないもの」を書き残すもの — LaravelのFeature Test中心の考え方 テストの数やカバレッジを目的にすると、守るべきものが見えなくなります。LaravelではFeature Testを中心に据え、複雑なルールにだけUnit Testを足す考え方と、境界値・異常系・冪等性・認可など重点的に書く観点をまとめます。