Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】Shipping a Lean DDD-Friendly Inventory API in Laravel 12

2025年09月18日に「Dev.to」が公開したITニュース「Shipping a Lean DDD-Friendly Inventory API in Laravel 12」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

Laravel 12でドメイン駆動設計(DDD)とクリーンアーキテクチャを取り入れ、在庫管理APIを構築した事例。4層構造でビジネスロジックをフレームワークから分離し、テストしやすく保守・拡張が容易なシステムを実現した。冪等性やAPI認証も導入し、堅牢なAPI開発の指針を示す。

ITニュース解説

このニュース記事は、Laravel 12とPHP 8.4を使って、在庫管理APIを開発した事例を紹介している。特に、ドメイン駆動設計(DDD)とクリーンアーキテクチャという設計思想を取り入れ、システムの長期的な保守性や拡張性を高めることに注力した開発プロセスが説明されている。システムエンジニアを目指す人にとって、大規模なアプリケーション開発で直面する課題と、それを解決するための実践的な設計パターンを学ぶ良い機会となるだろう。

開発されたAPIは、在庫アイテムの登録と取得を主な機能としている。このプロジェクトでは、コードを役割に応じて四つの層に分ける「四層アーキテクチャ」を採用している。これは、ドメイン層、アプリケーション層、インフラストラクチャ層、そしてインターフェース/HTTP層という構成である。さらに、APIのセキュリティを確保するための認証・認可、同じリクエストが複数回送信されてもデータが重複しないようにする멱等性(べきとうせい)の考慮、APIへのアクセス頻度を制限するレート制限、データベース操作を効率的に行うリポジトリパターン、そしてコードの品質を保証するためのテストも導入されている。

まず、システムの「心臓部」にあたるのが「ドメイン層」である。この層の目的は、ビジネスの核となるロジックとルールを純粋に表現することにある。例えば、在庫アイテムの名前は空であってはならない、在庫数は負の値になってはいけないといったビジネス上の制約が、ここに集約されている。この層では、特定のフレームワーク(Laravelなど)の機能には一切依存せず、ビジネスの言葉(ユビキタス言語)で概念が定義される。具体的には、「InventoryItem」というエンティティ(データと振る舞いを併せ持つオブジェクト)や、「Sku(商品コード)」、「Price(価格)」といった値オブジェクト(特定の値を表現するオブジェクト)が作られる。これらは、データを保持するだけでなく、そのデータの妥当性を保証する責任も持つ。また、データベースからデータを取得するための「InventoryItemRepositoryInterface」というインターフェースもこの層で定義され、具体的なデータベース実装の詳細を隠蔽している。これにより、ビジネスロジックはフレームワークから独立し、テストが容易で高速になるという大きなメリットがある。

次に、「アプリケーション層」は、ドメイン層で定義されたビジネスロジックを実行する「司令塔」の役割を果たす。ここでは、特定のユースケース(例えば「在庫アイテムを登録する」)ごとに処理の流れが定義される。入力データを受け取るための「CreateInventoryItemCommand」のようなコマンドオブジェクトや、処理結果を返すための「RegisterInventoryItemResult」のようなDTO(Data Transfer Object)が使われる。この層の「RegisterInventoryItemユースケース」は、バリデーション、ドメイン層のリポジトリインターフェースを通じたデータ永続化の依頼、そして멱等性サービスを通じた重複リクエストの防止など、一連の処理を調整する。重要なのは、この層もデータベースの具体的な種類や、APIがHTTPでアクセスされるかどうかといった「インフラの詳細」には関心を持たない点である。代わりに、時刻の取得やトランザクション管理、멱等性チェックといったシステム的な機能についても、それぞれインターフェースを通じて抽象的に依存することで、インフラの実装を柔軟に差し替えられるようになっている。

「インフラストラクチャ層」は、アプリケーション層が要求する具体的な機能を提供する「道具箱」である。ここでは、Laravelの機能が存分に活用される。例えば、データベースへのデータの読み書きは、LaravelのEloquentモデル(「InventoryItemModel」)を使って行われる。「InventoryItemRepository」は、ドメイン層で定義されたリポジトリインターフェースを実装し、ドメインのエンティティとEloquentモデルの間でデータを変換しながら、データベース操作を実行する。また、アプリケーション層で抽象的に使われていた「TransactionManagerInterface」や「IdempotencyServiceInterface」といったインターフェースも、この層で具体的なデータベーストランザクションや、専用のテーブルを使った멱等性チェックの実装が提供される。これらの具体的な実装は、Laravelのサービスプロバイダを通じて、アプリケーション層のインターフェースに結びつけられる。

「インターフェース/HTTP層」は、ユーザーや他のシステムがAPIにアクセスするための「窓口」である。ここでは、HTTPリクエストを受け取り、それをアプリケーション層のコマンドに変換し、アプリケーション層からの結果をHTTPレスポンスとして返す役割を担う。具体的には、「StoreInventoryItemRequest」のようなフォームリクエストクラスを使って、入力データのバリデーション(妥当性検証)を早期に行い、リクエストヘッダーに特定の情報(멱等性キーなど)が含まれていることを確認する。また、コントローラー(「InventoryItemController」)は、これらのリクエストを処理し、アプリケーション層を呼び出す。さらに、ドメイン層で発生した例外(例えば、重複するSKUで登録しようとした場合)を、HTTPの適切なステータスコード(例:409 Conflict)を持つJSONレスポンスに変換するミドルウェアもこの層に含まれる。APIのアクセス制御を行うポリシー(「InventoryItemPolicy」)もここで定義され、認証されたユーザーのトークンが特定の操作(読み書きなど)を許可されているかを検証する。

APIのセキュリティを確保するために、「認証、ポリシー、レート制限」も重要な要素である。Laravel Sanctumを用いて、APIの各ルートには認証が必須とされ、ユーザーが持っているAPIトークンに基づいて、どの操作を許可するかをポリシーで細かく制御する。例えば、「在庫を読み取る権限」と「在庫を書き込む権限」といった能力(ability)を定義し、ユーザーのトークンが適切な能力を持っている場合にのみ、操作が許可されるようにする。また、特定のAPIエンドポイントに対して、一定時間内に受け付けるリクエストの数を制限するレートリミッターを設定することで、システムへの過負荷を防ぐ。

データを永続化するための「データベーススキーマ」も適切に設計されている。「inventory_items」テーブルは、UUIDを主キーとし、SKUやステータスにはインデックスが張られ、通貨や金額といった情報も保持する。特に注目すべきは「idempotency_keys」テーブルで、これは멱等性を実現するために、各リクエストの一意なキー、ユーザー、リクエストの内容のハッシュ値、そしてそのリクエストに対するレスポンスを保存する。これにより、同じリクエストが複数回送信されても、一度目の処理結果が返されるだけで、データの重複を防ぐことができる。

開発されたコードの品質と信頼性を保証するために、「テスト」が非常に重要である。このプロジェクトでは、Pestというテストフレームワークを使って、簡潔な記述でテストが実装されている。具体的には、値オブジェクトやアプリケーション層のユースケース(멱等性チェックや重複SKUの検出を含む)の「単体テスト」が行われる。また、APIエンドポイントへの実際のHTTPリクエストをシミュレートし、データベースのリフレッシュ、Sanctum認証、そして期待されるHTTPステータスコードやレスポンス内容を検証する「結合テスト」も行われる。これにより、コードの変更が既存の機能に悪影響を与えないことや、ビジネスロジックが正しく実装されていることを確認できる。

このプロジェクトを通して得られた「学び」は多岐にわたる。ドメイン層を純粋に保つことで、ビジネスロジックのテストやリファクタリングが格段に容易になることが確認された。アプリケーション層でインターフェース(コントラクト)に依存することで、Laravelのような具体的なフレームワークの実装から独立し、テストがしやすくなる。ミドルウェアやグローバルな例外ハンドリングを活用することで、コントローラーのコードを簡潔に保ち、エラー処理のロジックを一箇所に集約できる。멱等性テーブルは、クライアントが安全にリクエストを再試行できるため、非常に価値のある機能である。また、認証ポリシーと能力を組み合わせることで、APIのセキュリティと柔軟なアクセス制御を実現できる。

今後の拡張として、システム内の異なるコンテキスト(例:注文管理)間で非同期に情報を伝達するためのドメインイベントの導入、在庫調整のような同時実行性が必要な操作のためのPATCHエンドポイントとトランザクションロックの追加、トラフィック増加時に멱等性層をRedisのような高速なKVSに移行する可能性、そしてリスト表示エンドポイントのパフォーマンスを向上させるためのCQRSリードモデルやキャッシングの導入などが挙げられている。

まとめると、このプロジェクトは、単にAPIを構築するだけでなく、ドメイン駆動設計とクリーンアーキテクチャという設計原則を実践することで、技術的にも組織的にもスケーラブルなシステムを構築する方法を示している。ビジネスルールを明確に分離し、アプリケーションサービスを通じて処理を調整し、Laravelをインフラ層のドライバとして活用することで、保守性、テスト性、そして将来的な拡張性に優れたコードベースを実現しているのである。

関連コンテンツ

関連IT用語