Skip to content
/ dto Public

A simple and lightweight implementation of Data Transfer Objects (DTO) in Laravel with optional casting support

License

Notifications You must be signed in to change notification settings

tailflow/dto

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Laravel Data Transfer Object

Latest Version on Packagist Build Status on GitHub Actions

A simple and lightweight implementation of Data Transfer Objects (DTO) in Laravel with optional casting support.

Under the hood it implements Laravel's Castable interface with a Laravel custom cast that handles serializing between the DataTransferObject (or a compatible array) and your JSON database column.

Installation

You can install the package via composer:

composer require tailflow/dto

Usage

1. Create your DataTransferObject or DataTransferObjectCollection

namespace App\DataTransferObjects;

use Tailflow\DataTransferObjects\DataTransferObject;

class Address extends DataTransferObject
{
    public string $country;
    public string $city;
    public string $street;
}
namespace App\DataTransferObjects;

use Tailflow\DataTransferObjects\DataTransferObjectCollection;

class WorkAddresses extends DataTransferObjectCollection 
{
    public static function getItemClass(): string
    {
        return Address::class;
    }
}

(Optional) 2. Configure your Eloquent attribute casting:

Note that this should be a jsonb or json column in your database schema.

namespace App\Models;

use App\DataTansferObjects\Address;
use App\DataTansferObjects\WorkAddresses;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    protected $casts = [
        'address' => Address::class,
        'work_addresses' => WorkAddresses::class,
    ];
}

3. Enjoy ~

Pass DTOs as arguments or use as return values, and get a nice autocompletion.

function getAddress(Address $originalAddress): Address 
{
    $address = new Address();
    $address->county = $originalAddress->country;
    $address->city = 'Tokyo';
    $address->street = '4-2-8 Shiba-koen';
  
    return $address;
}

// or

function getAddress(): Address 
{
    return new Address(
        [
            'country' => 'Japan',
            'city' => 'Tokyo',
            'street' => '4-2-8 Shiba-koen',
        ]
    );
}

On Eloquent models, you can now pass either an instance of your Address class, or even just an array with a compatible structure. It will automatically be cast between your class and JSON for storage and the data will be validated on the way in and out.

$workAddress = new Address();
$workAddress->country = 'Japan';
$workAddress->city = 'Osaka';

$user = User::create([
    // ...
    'address' => [
        'country' => 'Japan',
        'city' => 'Tokyo',
        'street' => '4-2-8 Shiba-koen',
    ],
    'work_addresses' => [
        $workAddress
    ]

]);

$residents = User::where('address->city', 'Tokyo')->get();

But the best part is that you can decorate your class with domain-specific methods to turn it into a powerful value object.

$user->address->toMapUrl();

$user->address->getCoordinates();

$user->address->getPostageCost($sender);

$user->address->calculateDistance($otherUser->address);

echo (string) $user->address;

License

The MIT License (MIT). Please see License File for more information.

About

A simple and lightweight implementation of Data Transfer Objects (DTO) in Laravel with optional casting support

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages