Why it is needed
- Isolates the internal model from the external API — a DB schema change will not break the API response
- Explicitly documents what data is passed between layers
- Convenient for validating input data (Request DTO) and shaping responses (Response DTO)
Example
class CreateUserDTO {
public function __construct(
public readonly string $name,
public readonly string $email,
public readonly string $password,
) {}
}
DTO vs Entity vs ViewModel
- Entity — a domain model object with identity (exists in the DB)
- DTO — a transport container with no identity
- ViewModel — a DTO specifically shaped for display in a UI/template