-
-
Notifications
You must be signed in to change notification settings - Fork 0
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.
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.
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
<?php
declare(strict_types=1);
namespace App\DTOs;
use Grazulex\LaravelArc\Support\Traits\ValidatesData;
use Grazulex\LaravelArc\Support\Traits\ConvertsData;
/**
* User data transfer object
*
* @property string $name User's name
* @property string $email User's email address
* @property int $age User's age
*/
final readonly class UserDto
{
use ValidatesData, ConvertsData;
public function __construct(
public string $name,
public string $email,
public int $age,
) {}
/**
* Get validation rules for this DTO
*/
public static function validationRules(): array
{
return [
'name' => ['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());
}
}
Laravel Arc generates modern PHP classes with:
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
Properties are defined as constructor parameters:
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
Automatic Laravel validation generation:
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.
Laravel Arc includes powerful traits:
use ValidatesData; // Validation methods
use ConvertsData; // Data conversion methods
use HasTimestamps; // Timestamp functionality (when trait added)
YAML with transformers:
fields:
name:
type: string
transformers: [trim, title_case]
email:
type: email
transformers: [trim, lowercase]
Generates transformation in factory methods:
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'],
);
}
YAML with traits:
header:
traits: [HasTimestamps, HasUuid]
Generates additional properties and methods:
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()
}
YAML with nested DTOs:
fields:
name: { type: string }
relations:
address:
type: has_one
class: AddressDto
Generates nested DTO handling:
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,
);
}
Provides validation methods:
// 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
Provides conversion methods:
// 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
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]
<?php
declare(strict_types=1);
namespace App\DTOs\Orders;
use Grazulex\LaravelArc\Support\Traits\ValidatesData;
use Grazulex\LaravelArc\Support\Traits\ConvertsData;
use Grazulex\LaravelArc\Support\Traits\HasTimestamps;
use Grazulex\LaravelArc\Support\Traits\HasUuid;
use Grazulex\LaravelArc\Support\Traits\HasStatus;
use Illuminate\Support\Collection;
/**
* Complete order data transfer object
*
* @property string $customer_name Customer's full name
* @property string $customer_email Customer's email address
* @property string $order_number Unique order identifier
* @property float $total_amount Order total amount
* @property string $currency Order currency
* @property string $shipping_address Shipping address
* @property Collection<OrderItemDto> $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']);
}
}
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
static::validationRules() // Get Laravel validation rules
static::validate(array $data) // Validate data
$dto->isValid() // Check if DTO is valid
$dto->getValidationErrors() // Get validation errors
$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
$dto->collect() // Wrap in Laravel Collection
$dto->pipe(callable $callback) // Pipeline processing
$dto->map(callable $callback) // Map over properties
$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
Laravel Arc generates optimized code:
// Efficient constructor with typed parameters
public function __construct(
public readonly string $name, // Direct property assignment
public readonly int $age, // No setter overhead
) {}
// Relations loaded only when accessed
public function getAddress(): ?AddressDto
{
return $this->address ??= AddressDto::from($this->addressData);
}
private static ?array $cachedRules = null;
public static function validationRules(): array
{
return self::$cachedRules ??= [
// ... validation rules
];
}
Now that you understand generated DTO structure:
- Collections - Working with arrays of DTOs
- Nested DTOs - Complex data structures
- Artisan Commands - CLI tools for generation
- Example API Integration - 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. ποΈ
Laravel Arc - Generate Type-Safe DTOs from YAML Definitions
π Home | π Get Started | π Examples | βοΈ Config
From YAML to Type-Safe Code - Made with β€οΈ for the Laravel community
π Home
- π Understanding YAML Structure
- π·οΈ Field Types
- π Field Transformers
- π Behavioral Traits
YAML β DTO β Type-Safe Code
Laravel Arc transforms your YAML definitions into powerful PHP DTOs with automatic validation, field transformers, and behavioral traits.
- π Get Started - Create your first DTO in 5 minutes
- π All Examples - Copy-paste ready examples
- β‘ Commands - CLI reference