# 🏗️ Generated DTO Structure Understanding what Laravel Arc generates helps you leverage the full power of your DTOs. This guide shows you exactly what code is created from your YAML definitions. ## The Generation Process ``` YAML Definition → Laravel Arc Parser → Generated PHP Class ↓ ↓ ↓ Schema Rules → Code Generation → Type-Safe DTO ``` Laravel Arc transforms your YAML into modern PHP 8.3+ classes with full type safety and rich functionality. ## Basic Generated Structure ### From This YAML: ```yaml header: class: UserDto namespace: App\DTOs fields: name: type: string required: true max_length: 255 email: type: email required: true age: type: integer min: 18 max: 120 ``` ### Generates This PHP: ```php ['required', 'string', 'max:255'], 'email' => ['required', 'email'], 'age' => ['required', 'integer', 'min:18', 'max:120'], ]; } /** * Create DTO from array with validation */ public static function fromValidated(array $data): static { validator($data, static::validationRules())->validate(); return static::from($data); } /** * Create DTO from Laravel request */ public static function fromRequest(\Illuminate\Http\Request $request): static { return static::fromValidated($request->all()); } } ``` ## Core Components ### 1. Class Declaration Laravel Arc generates modern PHP classes with: ```php declare(strict_types=1); // Strict typing final readonly class UserDto // Immutable by default ``` **Key Features:** - `declare(strict_types=1)` - Full type enforcement - `final` - Prevents inheritance (configurable) - `readonly` - Immutable properties (configurable) - Proper namespace and imports ### 2. Constructor Properties Properties are defined as constructor parameters: ```php public function __construct( public string $name, // Required field public string $email, // Required field public int $age, // Required field public ?string $nickname = null, // Optional field public bool $active = true, // Field with default ) {} ``` **Property Features:** - **Type hints** from YAML field types - **Visibility** (public by default) - **Readonly** for immutability - **Nullable** when specified - **Default values** from YAML ### 3. Validation Rules Automatic Laravel validation generation: ```php public static function validationRules(): array { return [ 'name' => ['required', 'string', 'max:255'], 'email' => ['required', 'email', 'unique:users,email'], 'age' => ['integer', 'min:18', 'max:120'], 'status' => ['string', 'in:active,inactive,pending'], ]; } ``` Rules are generated from YAML field definitions automatically. ### 4. Helper Traits Laravel Arc includes powerful traits: ```php use ValidatesData; // Validation methods use ConvertsData; // Data conversion methods use HasTimestamps; // Timestamp functionality (when trait added) ``` ## Advanced Generated Features ### With Transformers YAML with transformers: ```yaml fields: name: type: string transformers: [trim, title_case] email: type: email transformers: [trim, lowercase] ``` Generates transformation in factory methods: ```php public static function from(array $data): static { // Apply transformers $data['name'] = TitleCase::transform(Trim::transform($data['name'] ?? '')); $data['email'] = Lowercase::transform(Trim::transform($data['email'] ?? '')); return new static( name: $data['name'], email: $data['email'], ); } ``` ### With Behavioral Traits YAML with traits: ```yaml header: traits: [HasTimestamps, HasUuid] ``` Generates additional properties and methods: ```php final readonly class UserDto { use ValidatesData, ConvertsData, HasTimestamps, HasUuid; public function __construct( public string $name, public string $email, public string $uuid, // From HasUuid public ?\DateTime $created_at = null, // From HasTimestamps public ?\DateTime $updated_at = null, // From HasTimestamps ) {} // Additional trait methods available: // $dto->getUuid() // $dto->touch() // $dto->wasRecentlyCreated() } ``` ### With Relations YAML with nested DTOs: ```yaml fields: name: { type: string } relations: address: type: has_one class: AddressDto ``` Generates nested DTO handling: ```php public function __construct( public string $name, public ?AddressDto $address = null, ) {} public static function from(array $data): static { // Handle nested DTO creation $address = isset($data['address']) ? AddressDto::from($data['address']) : null; return new static( name: $data['name'], address: $address, ); } ``` ## Trait Integration ### ValidatesData Trait Provides validation methods: ```php // Validate data against DTO rules UserDto::validate($data); // Returns Validator instance // Create with validation $user = UserDto::fromValidated($data); // Validate current DTO data $user->isValid(); // boolean $user->getValidationErrors(); // array ``` ### ConvertsData Trait Provides conversion methods: ```php // Export to different formats $user->toArray(); // Array $user->toJson(); // JSON string $user->toXml(); // XML string $user->toCsv(); // CSV string $user->toYaml(); // YAML string // Collection methods $user->collect(); // Laravel Collection $user->pipe($callback); // Pipeline processing ``` ## Real-World Generated Example ### Complex YAML Definition ```yaml header: class: OrderDto namespace: App\DTOs\Orders traits: [HasTimestamps, HasUuid, HasStatus] description: "Complete order data transfer object" trait_config: HasStatus: default: "pending" states: [pending, processing, shipped, delivered, cancelled] fields: # Customer information customer_name: type: string required: true max_length: 255 transformers: [trim, title_case] customer_email: type: email required: true transformers: [trim, lowercase] # Order details order_number: type: string required: true unique: true pattern: "^ORD-[0-9]{6}$" total_amount: type: decimal precision: 10 scale: 2 min: 0 currency: type: string default: "USD" enum: [USD, EUR, GBP, CAD] # Shipping shipping_address: type: text required: true max_length: 500 relations: items: type: has_many class: OrderItemDto export: formats: [json, xml] exclude: [internal_notes] ``` ### Generated OrderDto Class ```php $items Order items * @property string $uuid Unique identifier * @property string $status Order status * @property \DateTime|null $created_at Creation timestamp * @property \DateTime|null $updated_at Last update timestamp */ final readonly class OrderDto { use ValidatesData, ConvertsData, HasTimestamps, HasUuid, HasStatus; public function __construct( public string $customer_name, public string $customer_email, public string $order_number, public float $total_amount, public string $currency = 'USD', public string $shipping_address, public Collection $items, public string $uuid, public string $status = 'pending', public ?\DateTime $created_at = null, public ?\DateTime $updated_at = null, ) {} /** * Get validation rules for this DTO */ public static function validationRules(): array { return [ 'customer_name' => ['required', 'string', 'max:255'], 'customer_email' => ['required', 'email'], 'order_number' => ['required', 'string', 'unique:orders,order_number', 'regex:/^ORD-[0-9]{6}$/'], 'total_amount' => ['required', 'numeric', 'decimal:0,2', 'min:0'], 'currency' => ['string', 'in:USD,EUR,GBP,CAD'], 'shipping_address' => ['required', 'string', 'max:500'], 'items' => ['required', 'array'], 'items.*' => ['array'], // OrderItemDto validation ]; } /** * Create DTO from array with transformations */ public static function from(array $data): static { // Apply transformers $data['customer_name'] = TitleCase::transform(Trim::transform($data['customer_name'] ?? '')); $data['customer_email'] = Lowercase::transform(Trim::transform($data['customer_email'] ?? '')); // Handle nested DTOs $items = collect($data['items'] ?? []) ->map(fn($item) => OrderItemDto::from($item)); // Generate UUID if not provided $data['uuid'] ??= Str::uuid()->toString(); return new static( customer_name: $data['customer_name'], customer_email: $data['customer_email'], order_number: $data['order_number'], total_amount: (float) $data['total_amount'], currency: $data['currency'] ?? 'USD', shipping_address: $data['shipping_address'], items: $items, uuid: $data['uuid'], status: $data['status'] ?? 'pending', created_at: isset($data['created_at']) ? new \DateTime($data['created_at']) : null, updated_at: isset($data['updated_at']) ? new \DateTime($data['updated_at']) : null, ); } /** * Export to array (respects export configuration) */ public function toArray(): array { return [ 'customer_name' => $this->customer_name, 'customer_email' => $this->customer_email, 'order_number' => $this->order_number, 'total_amount' => $this->total_amount, 'currency' => $this->currency, 'shipping_address' => $this->shipping_address, 'items' => $this->items->map->toArray()->all(), 'uuid' => $this->uuid, 'status' => $this->status, 'created_at' => $this->created_at?->format('c'), 'updated_at' => $this->updated_at?->format('c'), // 'internal_notes' excluded per export config ]; } /** * Get total order value including tax */ public function getTotalWithTax(float $taxRate = 0.1): float { return $this->total_amount * (1 + $taxRate); } /** * Get order items count */ public function getItemsCount(): int { return $this->items->count(); } /** * Check if order can be cancelled */ public function canBeCancelled(): bool { return in_array($this->status, ['pending', 'processing']); } } ``` ## Generated Method Categories ### 1. Factory Methods ```php static::from(array $data) // Create from array static::fromValidated(array $data) // Create with validation static::fromRequest(Request $request) // Create from HTTP request static::fromJson(string $json) // Create from JSON ``` ### 2. Validation Methods ```php static::validationRules() // Get Laravel validation rules static::validate(array $data) // Validate data $dto->isValid() // Check if DTO is valid $dto->getValidationErrors() // Get validation errors ``` ### 3. Conversion Methods ```php $dto->toArray() // Convert to array $dto->toJson() // Convert to JSON $dto->toXml() // Convert to XML $dto->toCsv() // Convert to CSV $dto->toYaml() // Convert to YAML ``` ### 4. Collection Methods ```php $dto->collect() // Wrap in Laravel Collection $dto->pipe(callable $callback) // Pipeline processing $dto->map(callable $callback) // Map over properties ``` ### 5. Utility Methods ```php $dto->with(array $changes) // Create copy with changes $dto->only(array $keys) // Get subset of properties $dto->except(array $keys) // Get all except specified $dto->isEmpty() // Check if empty $dto->isNotEmpty() // Check if not empty ``` ## Performance Optimizations Laravel Arc generates optimized code: ### 1. Minimal Object Creation ```php // Efficient constructor with typed parameters public function __construct( public readonly string $name, // Direct property assignment public readonly int $age, // No setter overhead ) {} ``` ### 2. Lazy Loading for Relations ```php // Relations loaded only when accessed public function getAddress(): ?AddressDto { return $this->address ??= AddressDto::from($this->addressData); } ``` ### 3. Cached Validation Rules ```php private static ?array $cachedRules = null; public static function validationRules(): array { return self::$cachedRules ??= [ // ... validation rules ]; } ``` ## What's Next? Now that you understand generated DTO structure: - **[Collections](Collections.md)** - Working with arrays of DTOs - **[Nested DTOs](Nested-DTOs.md)** - Complex data structures - **[Artisan Commands](Artisan-Commands.md)** - CLI tools for generation - **[Example API Integration](Example-API-Integration.md)** - Real-world usage --- *Understanding the generated code helps you leverage the full power of Laravel Arc DTOs. Every YAML definition becomes a rich, type-safe PHP class.* 🏗️