Introduction #
As Laravel applications grow, handling raw arrays and unstructured request data becomes harder to maintain and debug. This is where Data Transfer Objects (DTOs) come in.
DTOs provide a clean, predictable way to move data between layers without mixing concerns.
What is a DTO? #
A Data Transfer Object is a simple object that carries structured data. It contains:
- Typed properties
- No business logic
- A single responsibility: transporting data
The Problem with Arrays #
Most Laravel apps rely heavily on arrays:
$request->all()$data['email']$payload['user']['name']
This approach:
- Lacks type safety
- Breaks easily during refactoring
- Makes code harder to read and test
Why DTOs Are Better #
DTOs give you:
- ✅ Strong typing
- ✅ Clear contracts between layers
- ✅ IDE autocomplete & static analysis
- ✅ Safer refactoring
- ✅ Cleaner controllers and services
Example DTO in Laravel #
final class CreateUserDTO
{
public function __construct(
public string $name,
public string $email,
public string $password,
) {}
}
Usage inside a controller or service:
$dto = new CreateUserDTO(
name: $request->name,
email: $request->email,
password: $request->password,
);
Where DTOs Shine the Most
Service layers
Action classes
API request handling
Background jobs
Domain-driven design (DDD)
----------
DTOs vs Form Requests
| Feature | DTO | Form Request |
| -------------- | --- | ------------ |
| Validation | ❌ | ✅ |
| Data Structure | ✅ | ⚠️ |
| Business Logic | ❌ | ❌ |
| Reusability | ✅ | ⚠️ |
👉 Best practice: Form Request validates, DTO structures data
-------------
Final Thoughts
DTOs are not about complexity.
They are about clarity, safety, and long-term maintainability.
If you care about clean architecture in Laravel, DTOs are a must-have tool.