Super Simple DTO
Creating data transfer objects with the power of php objects. No php attributes, no reflection api, and no other under the hook work.
This is a laravel package and laravel/framework
is part of the package dependencies. Please, make sure you have no problem with that before using.
Why Bother.
The spatie team has already created an awesome package that serves as a great solution for DTO objects. But, for me, it's full of features that I don't use and it seems like an overkill for me when I just wanted simple solution for DTO work.
Installation
You can install the package via composer:
composer require mohammedmanssour/super-simple-dto
Usage
- Apply the
AsDTO
trait to your data object
use MohammedManssour\DTO\Concerns\AsDTO;
class UserData
{
use AsDTO;
public string $name;
public string $email;
public BalanceData $balance;
public Status $status;
}
- use on of these static methods to convert data into DTP:
fromCollection
: converts collections to DTO objects.fromArray
: converts array to DTO objects.fromModel
: converts model to DTO objects. It works with the data available with$model->getAttributes()
method.fromRequest
: converts laravel requests to DTO objects. It works with the data available withvalidated()
. In casevalidated
method is not available, it'll use theall()
method. You can also force using request'sall
method by passing true as a second parameter.
UserData::fromCollection(collect([]));
UserData::fromArray([]);
UserData::fromModel($model);
UserData::fromRequest($request);
How DTO is populated:
The AsDTO
will assign values to DTO attributes depending of the keys. and attributes that has no key match will not be initialized/assigned
$data = [
'name' => 'Mohammed Manssour',
'email' => '[email protected]'
];
$dto = UserData::fromArray();
$this->assertEquals($data['name'], $dto->name);
$this->assertEquals($data['email'], $dto->email);
$this->assertFalse(isset($dto->balance));
$this->assertFalse(isset($dto->status));
Handling special attributes:
In case you have an attribute that needs special care. you can add a method to your dto than have the same name as your attribute and take care of the conversion.
use MohammedManssour\DTO\Concerns\AsDTO;
class BalanceData
{
use AsDTO;
public float $bitcoin;
public int $usdollar;
}
enum Status: string
{
case Active = 'active';
case Suspended = 'suspended';
}
class UserData
{
use AsDTO;
....
public BalanceData $balance;
public Status $status;
public function balance($value)
{
return $this->balance = BalanceData::fromArray($value);
}
public function status($value)
{
return $this->status = Status::from($value);
}
}
$data = [
'balance' => [
'bitcoin' => 10,
'usdollar' => 100
],
'status' => 'active'
];
$dto = UserData::fromArray($data)
$this->assertInstanceOf(BalanceData::class, $dto->balance);
$this->assertEquals($data['balance']['bitcoin'], $dto->balance->bitcoint);
$this->assertEquals($data['balance']['usdollar'], $dto->balance->usdollart);
$this->assertInstanceOf(Status::class, $dto->status);
$this->assertEquals(Status::Active, $dto->status);
converting DTO to array
You can convert dto to array using DTO method
$arr = $dto->toArray()
Testing
composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.