Laravel Clean Architecture
Priority: P1 (HIGH)
Workflow: Add a Domain Feature
- Create domain folder —
app/Domains/Order/{Actions,DTOs,Contracts}/. - Define DTO — Create a
readonly classwith typed constructor properties. - Create contract — Define a repository interface in
Contracts/. - Implement repository — Build Eloquent implementation; bind in
AppServiceProvider. - Write Action class — Single-responsibility use-case logic consuming the DTO.
- Verify bindings — Run
php artisan tinkerand resolve the interface to confirm DI works.
Action + DTO Example
See implementation examples for Action class with DTO and domain structure patterns.
Implementation Guidelines
Domain-Driven Design (DDD)
- Grouping: Organize code in
app/Domains/Order/{Actions,DTOs,Contracts}/. Group by business domain (User, Order, Payment) — not by type (Controllers, Models). - Core Models: Keep standard Eloquent models in
app/Models/. - Separation: Never put Eloquent queries in controllers; delegate to Action classes for use-case logic.
Data Transfer Objects (DTOs)
- Immutability: Use
readonly class(PHP 8.2+) orreadonlyproperties (PHP 8.1+). DTOs cross boundaries — pass between layers instead of raw arrays or Eloquent models.
Repository Pattern & Decoupling
- Interfaces: Create
Contracts/OrderRepository interfaceand implementEloquentOrderRepository. - Binding: Bind interfaces to implementations in
AppServiceProvidervia$this->app->bind(OrderRepository::class, EloquentOrderRepository::class). - Usage: Inject interfaces into your actions/services.
- Layer Flow: Controller → Action → Repository Interface → Eloquent. DTOs cross boundaries at every layer transition.
Anti-Patterns
- No Eloquent in Controllers: Bridge layers with DTOs and Actions.
- No raw arrays across layers: Use typed
readonlyDTOs. - No God Services: Break into single-responsibility Actions.
- No concrete dependencies: Depend on Interfaces, not implementations.