Skip to content

Understanding YAML Structure

Jean-Marc Strauven edited this page Aug 6, 2025 · 1 revision

πŸ“ Understanding YAML Structure

The heart of Laravel Arc is the YAML definition file. This page explains the complete YAML schema and how it translates to powerful PHP DTOs.

The YAML β†’ PHP Flow

YAML Definition β†’ Laravel Arc Parser β†’ Generated DTO Class
      ↓                    ↓                   ↓
Schema Rules    β†’    Code Generation    β†’  Type-Safe PHP

Understanding this flow is key to mastering Laravel Arc.

Complete YAML Schema

Here's the full structure of a Laravel Arc YAML file:

# Header section - Defines the class metadata
header:
  class: UserDto                    # Generated class name
  namespace: App\DTOs              # PHP namespace
  description: "User DTO"         # Class documentation
  extends: BaseDto                 # Optional parent class
  implements: [UserInterface]     # Optional interfaces
  traits: [HasTimestamps, HasUuid] # Behavioral traits
  
# Fields section - Defines all properties
fields:
  field_name:
    type: string                   # Field type (required)
    required: true                 # Validation rule
    default: "value"              # Default value
    description: "Field docs"     # Property documentation
    transformers: [trim, title]   # Data transformers
    validation: ["min:3"]         # Custom validation
    
# Relations section - Defines nested DTOs
relations:
  address:
    type: has_one
    class: AddressDto
    
# Export section - Configure output formats
export:
  formats: [json, xml, csv]
  
# Validation section - Global validation settings
validation:
  stop_on_first_failure: true

Header Section

The header section defines metadata about your generated DTO class:

header:
  # Required fields
  class: ProductDto                    # The generated class name
  namespace: App\DTOs\Products        # PHP namespace for the class
  
  # Optional fields
  description: "Product data object"   # Class docblock description
  extends: BaseDto                     # Parent class to extend
  implements: [JsonSerializable]      # Interfaces to implement
  traits: [HasTimestamps, HasUuid]    # Behavioral traits to use
  final: true                         # Make class final (default: true)
  readonly: true                      # Make properties readonly (default: true)

Generated Header Example

header:
  class: UserDto
  namespace: App\DTOs
  description: "User data transfer object with validation"
  traits: [HasTimestamps]

Generates:

<?php

declare(strict_types=1);

namespace App\DTOs;

use Grazulex\LaravelArc\Support\Traits\ValidatesData;
use Grazulex\LaravelArc\Support\Traits\ConvertsData;
use Grazulex\LaravelArc\Support\Traits\HasTimestamps;

/**
 * User data transfer object with validation
 */
final readonly class UserDto
{
    use ValidatesData, ConvertsData, HasTimestamps;
    
    // ... rest of the class
}

Fields Section

The fields section is where you define all properties of your DTO:

Basic Field Definition

fields:
  name:
    type: string      # Field type (required)
    required: true    # Make field required
    description: "User's full name"

Complete Field Options

fields:
  email:
    # Core properties
    type: email                    # Field type
    required: true                 # Required validation
    nullable: false                # Allow null values
    default: null                  # Default value
    
    # Validation rules
    max_length: 255               # String max length
    min_length: 3                 # String min length
    min: 1                        # Numeric minimum
    max: 100                      # Numeric maximum
    enum: [active, inactive]      # Allowed values
    unique: true                  # Unique validation
    
    # Data transformation
    transformers: [trim, lowercase] # Data transformers
    
    # Custom validation
    validation: ["email:rfc"]      # Additional Laravel rules
    
    # Documentation
    description: "User email address"
    example: "[email protected]"
    
    # Advanced options
    auto_fill: true               # Auto-fill with current timestamp/UUID
    cast: "datetime"              # Type casting
    hidden: false                 # Hide from toArray() output

Field Types

Laravel Arc supports 65+ field types through ModelSchema integration:

Basic Types

fields:
  name: { type: string }
  age: { type: integer }
  price: { type: decimal, precision: 8, scale: 2 }
  active: { type: boolean }
  created_at: { type: datetime }
  metadata: { type: json }

Advanced Types (ModelSchema Integration)

fields:
  # Geographic types
  location: { type: point }
  boundary: { type: polygon }
  path: { type: linestring }
  
  # Network types
  ip_address: { type: ipAddress }
  mac_address: { type: macAddress }
  
  # File types
  avatar: { type: image }
  document: { type: file }
  
  # Specialized types
  color: { type: color }
  uuid: { type: uuid }
  slug: { type: slug }

Collection Types

fields:
  # Array of strings
  tags:
    type: array
    items:
      type: string
      
  # Array of objects
  addresses:
    type: array
    items:
      type: object
      class: AddressDto

Field Transformers

Transformers automatically modify data when creating DTOs:

fields:
  name:
    type: string
    transformers: [trim, title_case]  # "  john doe  " β†’ "John Doe"
    
  email:
    type: email
    transformers: [trim, lowercase]   # "  [email protected]  " β†’ "[email protected]"
    
  slug:
    type: string
    transformers: [slugify]           # "Hello World!" β†’ "hello-world"

Available transformers:

  • trim - Remove whitespace
  • lowercase - Convert to lowercase
  • uppercase - Convert to uppercase
  • title_case - Title case conversion
  • slugify - Create URL-friendly slug
  • normalize - Unicode normalization

Relations Section

Define relationships to other DTOs:

relations:
  # Single related object
  address:
    type: has_one
    class: AddressDto
    required: false
    
  # Collection of related objects
  orders:
    type: has_many
    class: OrderDto
    
  # Polymorphic relationship
  commentable:
    type: morph_to
    classes: [PostDto, ProductDto]

Validation Integration

Laravel Arc automatically generates Laravel validation rules:

From YAML:

fields:
  email:
    type: email
    required: true
    max_length: 255
    unique: true

Generated Validation:

public static function validationRules(): array
{
    return [
        'email' => ['required', 'email', 'max:255', 'unique:users,email'],
    ];
}

Custom Validation Rules

fields:
  password:
    type: string
    required: true
    validation: ["min:8", "confirmed", "regex:/^.*(?=.{3,})(?=.*[a-zA-Z])(?=.*[0-9]).*$/"]

Behavioral Traits

Add common functionality with traits:

header:
  traits: [HasTimestamps, HasUuid, SoftDeletes, HasTags]

# HasTimestamps adds:
# - created_at: datetime
# - updated_at: datetime

# HasUuid adds:
# - uuid: string (auto-generated)

# SoftDeletes adds:
# - deleted_at: datetime|null

# HasTags adds:
# - tags: array of strings

Export Configuration

Configure how DTOs export data:

export:
  formats: [json, xml, csv, yaml]     # Available export formats
  exclude: [password, secret_key]     # Fields to exclude from exports
  include_nulls: false                # Include null values in exports
  date_format: "Y-m-d H:i:s"        # Date formatting

Complete Real-World Example

Here's a comprehensive example showcasing all features:

header:
  class: AdvancedUserDto
  namespace: App\DTOs\Users
  description: "Advanced user DTO with full feature set"
  traits: [HasTimestamps, HasUuid]

fields:
  # Basic information
  name:
    type: string
    required: true
    max_length: 255
    transformers: [trim, title_case]
    description: "User's full name"
    
  email:
    type: email
    required: true
    unique: true
    transformers: [trim, lowercase]
    validation: ["email:rfc,dns"]
    
  # Numeric fields
  age:
    type: integer
    min: 18
    max: 120
    description: "User's age in years"
    
  # Enums and defaults
  status:
    type: string
    default: "pending"
    enum: [pending, active, inactive, banned]
    
  # Geographic data
  location:
    type: point
    nullable: true
    description: "User's geographic location"
    
  # JSON data
  preferences:
    type: json
    default: {}
    description: "User preferences as JSON"
    
  # Collections
  tags:
    type: array
    items:
      type: string
    transformers: [trim, lowercase]

relations:
  profile:
    type: has_one
    class: UserProfileDto
    
  addresses:
    type: has_many
    class: AddressDto

export:
  formats: [json, xml]
  exclude: [password_hash]
  date_format: "c"  # ISO 8601 format

validation:
  stop_on_first_failure: false

YAML Best Practices

1. Consistent Naming

# Good - snake_case for field names
fields:
  first_name: { type: string }
  last_name: { type: string }
  created_at: { type: datetime }

# Avoid - inconsistent naming
fields:
  firstName: { type: string }  # camelCase
  last_name: { type: string }  # snake_case
  CreatedAt: { type: datetime } # PascalCase

2. Logical Field Grouping

fields:
  # Personal information
  first_name: { type: string, required: true }
  last_name: { type: string, required: true }
  birth_date: { type: date }
  
  # Contact information
  email: { type: email, required: true }
  phone: { type: string }
  
  # System fields
  status: { type: string, default: "active" }
  created_at: { type: datetime, auto_fill: true }

3. Clear Documentation

fields:
  payment_amount:
    type: decimal
    precision: 10
    scale: 2
    min: 0
    description: "Payment amount in cents (e.g., 1000 = $10.00)"
    example: 1500

Common YAML Patterns

API Request DTO

header:
  class: CreateUserRequestDto
  namespace: App\DTOs\Requests

fields:
  name: { type: string, required: true, max_length: 255 }
  email: { type: email, required: true, unique: true }
  password: { type: string, required: true, min_length: 8 }
  terms_accepted: { type: boolean, required: true }

API Response DTO

header:
  class: UserResponseDto
  namespace: App\DTOs\Responses
  traits: [HasTimestamps]

fields:
  id: { type: integer, required: true }
  name: { type: string, required: true }
  email: { type: email, required: true }
  status: { type: string, required: true }

export:
  exclude: [password, secret_key]

Configuration DTO

header:
  class: DatabaseConfigDto
  namespace: App\DTOs\Config

fields:
  host: { type: string, default: "localhost" }
  port: { type: integer, default: 3306 }
  database: { type: string, required: true }
  username: { type: string, required: true }
  password: { type: string, required: true, hidden: true }
  charset: { type: string, default: "utf8mb4" }
  ssl: { type: boolean, default: false }

What's Next?

Now that you understand the YAML structure:


The YAML structure is the foundation of Laravel Arc. Master it, and you'll be able to create powerful, type-safe DTOs effortlessly. πŸš€

πŸš€ Laravel Arc Wiki

🏠 Home

πŸš€ Getting Started

πŸ“š Core Concepts

πŸ—οΈ Advanced Features

βš™οΈ Configuration & CLI

🌐 Real-World Examples


🎯 Key Concepts

YAML β†’ DTO β†’ Type-Safe Code

Laravel Arc transforms your YAML definitions into powerful PHP DTOs with automatic validation, field transformers, and behavioral traits.

πŸ”— Quick Links

Clone this wiki locally