You are viewing documentation for an outdated version. It is no longer supported!

Nested DTOs

Imagine that your Person DTO accepts more complex properties, e.g. an address DTO. Normally, you would manually create that address DTO first, in order to populate your main DTO. However, if you use the Dto abstraction with Laravel's Service Containeropen in new window, populating nested DTOs will be automatically handled for you.

Prerequisite

If you are using the Dto component within a typical Laravel application, then you do not have to do anything. A Service Container should already be available.

If you are using this Dto package outside a Laravel application, then you must ensure that a Service Container has been initialised. Consider using this package's Service Container (a slightly adapted version of Laravel's Service Container).

Example

The following example shows two DTOs; Address and Person.

Address DTO

class Address extends Dto
{
    protected ?string $street = '';

    public function setStreet(?string $street)
    {
        $this->street = $street;
    }

    public function getStreet() : ?string
    {
        return $this->street;
    }
}

Person DTO

class Person extends Dto implements PersonInterface
{
    protected ?string $name = '';
    
    protected ?int $age = 0;
 
    protected ?Address $address = null;
 
    // ... getters and setters for name and age not shown ... //

     public function setAddress(?Address $address)
     {
         $this->address = $address;
     }
     
     public function getAddress() : ?Address
     {
         return $this->address;
     }
}

Resolving Nested Dependencies

When populating your DTO, just pass in the data as your normally do. Eventual nested dependencies will automatically be attempted resolved and populated. Consider the following example:

$data = [
    'name' => 'Arial Jackson',
    'age' => 42,
    
    // Notice that we are NOT passing an instance of Address, but an array instead!
    'address' => [
        'street' => 'Somewhere str. 44'
    ]
];

$person = new Person($data);                                    
$address = $person->getAddress(); // Address DTO instance

In the above example, the Address DTO is automatically resolved and populated by the Service Containeropen in new window.

Note

If unable to resolve a nested dependency, the Service Container will fail with a \Psr\Container\ContainerExceptionInterface.