Nested DTOs
Learn how to work with complex nested DTO structures.
What are Nested DTOs?
Section titled “What are Nested DTOs?”Nested DTOs allow you to compose complex data structures from simpler DTOs:
class AddressDTO extends SimpleDTO{ public function __construct( public readonly string $street, public readonly string $city, public readonly string $country, ) {}}
class UserDTO extends SimpleDTO{ public function __construct( public readonly string $name, public readonly AddressDTO $address, ) {}}
$user = UserDTO::fromArray([ 'name' => 'John Doe', 'address' => [ 'street' => '123 Main St', 'city' => 'New York', 'country' => 'USA', ],]);Basic Nesting
Section titled “Basic Nesting”Single Nested DTO
Section titled “Single Nested DTO”class ProfileDTO extends SimpleDTO{ public function __construct( public readonly string $bio, public readonly string $avatar, ) {}}
class UserDTO extends SimpleDTO{ public function __construct( public readonly string $name, public readonly ProfileDTO $profile, ) {}}Optional Nested DTO
Section titled “Optional Nested DTO”class UserDTO extends SimpleDTO{ public function __construct( public readonly string $name, public readonly ?AddressDTO $address = null, ) {}}Multiple Levels
Section titled “Multiple Levels”Three-Level Nesting
Section titled “Three-Level Nesting”class CityDTO extends SimpleDTO{ public function __construct( public readonly string $name, public readonly string $zipCode, ) {}}
class AddressDTO extends SimpleDTO{ public function __construct( public readonly string $street, public readonly CityDTO $city, ) {}}
class UserDTO extends SimpleDTO{ public function __construct( public readonly string $name, public readonly AddressDTO $address, ) {}}Collections of Nested DTOs
Section titled “Collections of Nested DTOs”Array of DTOs
Section titled “Array of DTOs”class OrderItemDTO extends SimpleDTO{ public function __construct( public readonly string $product, public readonly int $quantity, public readonly float $price, ) {}}
class OrderDTO extends SimpleDTO{ public function __construct( public readonly int $orderId, public readonly array $items, // Array of OrderItemDTO ) {}}
$order = OrderDTO::fromArray([ 'orderId' => 123, 'items' => [ ['product' => 'Widget', 'quantity' => 2, 'price' => 10.00], ['product' => 'Gadget', 'quantity' => 1, 'price' => 20.00], ],]);Using DataCollection
Section titled “Using DataCollection”use Event4u\DataHelpers\SimpleDTO\DataCollection;
class OrderDTO extends SimpleDTO{ public function __construct( public readonly int $orderId, public readonly DataCollection $items, ) {}}Real-World Example
Section titled “Real-World Example”E-Commerce Order
Section titled “E-Commerce Order”class ProductDTO extends SimpleDTO{ public function __construct( public readonly int $id, public readonly string $name, public readonly float $price, ) {}}
class OrderItemDTO extends SimpleDTO{ public function __construct( public readonly ProductDTO $product, public readonly int $quantity, ) {}
#[Computed] public function total(): float { return $this->product->price * $this->quantity; }}
class ShippingAddressDTO extends SimpleDTO{ public function __construct( public readonly string $street, public readonly string $city, public readonly string $zipCode, public readonly string $country, ) {}}
class OrderDTO extends SimpleDTO{ public function __construct( public readonly int $orderId, public readonly DataCollection $items, public readonly ShippingAddressDTO $shippingAddress, public readonly Carbon $orderDate, ) {}
#[Computed] public function total(): float { return $this->items->sum(fn($item) => $item->total()); }}Best Practices
Section titled “Best Practices”Use Type Hints
Section titled “Use Type Hints”// ✅ Good - with type hintpublic readonly AddressDTO $address;
// ❌ Bad - no type hintpublic readonly $address;Keep Nesting Shallow
Section titled “Keep Nesting Shallow”// ✅ Good - 2-3 levelsUserDTO -> AddressDTO -> CityDTO
// ❌ Bad - too deepUserDTO -> ProfileDTO -> SettingsDTO -> PreferencesDTO -> ThemeDTOUse Collections for Arrays
Section titled “Use Collections for Arrays”// ✅ Good - use DataCollectionpublic readonly DataCollection $items;
// ❌ Bad - plain arraypublic readonly array $items;See Also
Section titled “See Also”- Collections - Work with collections
- Type Casting - Automatic type conversion
- Creating DTOs - Creation methods