PHPackages                             novius/laravel-dto - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. novius/laravel-dto

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

novius/laravel-dto
==================

A simple and extensible DTO package for Laravel

1.0.12(2mo ago)0175AGPL-3.0-or-laterPHPPHP ^8.2CI passing

Since Apr 14Pushed 2mo agoCompare

[ Source](https://github.com/novius/laravel-dto)[ Packagist](https://packagist.org/packages/novius/laravel-dto)[ Docs](https://github.com/novius/laravel-dto)[ RSS](/packages/novius-laravel-dto/feed)WikiDiscussions main Synced 3w ago

READMEChangelog (10)Dependencies (9)Versions (14)Used By (0)

Laravel DTO
===========

[](#laravel-dto)

A simple and extensible DTO (Data Transfer Objects) package for Laravel.

This package allows you to define structured data objects with built-in validation, default values, and automatic casting, while supporting both camelCase and snake\_case naming conventions.

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require novius/laravel-dto
```

Artisan Command
---------------

[](#artisan-command)

You can easily generate a new DTO class using the following Artisan command:

```
php artisan make:dto UserDto
```

By default, the class will be created in the `app/Dtos` directory.

Basic Usage
-----------

[](#basic-usage)

To create a DTO, simply extend the `Novius\LaravelDto\Dto` class and define your properties.

```
use Novius\LaravelDto\Dto;

/**
 * @property string $name
 * @property int $age
 * @property ?string $email
 *
 * @method string getName()
 * @method self setName(string $name)
 * @method int getAge()
 * @method self setAge(int $age)
 * @method ?string getEmail()
 * @method self setEmail(?string $email)
 */
class UserDto extends Dto
{
    protected string $name;
    protected int $age;
    protected ?string $email;
}

// Instantiation from an array
$dto = new UserDto([
    'name' => 'John Doe',
    'age' => 30,
    'email' => 'john@example.com',
]);

echo $dto->name; // John Doe
```

If you try to pass a property that is not defined in the class, an `InvalidArgumentException` will be thrown.

Features
--------

[](#features)

### Validation

[](#validation)

Override the `rules()` method to define Laravel validation rules for your properties.

```
protected function rules(): array
{
    return [
        'name' => 'required|string|min:3',
        'age' => 'required|integer|min:18',
        'email' => 'nullable|email',
    ];
}
```

You can also customize validation messages and attributes by overriding the `messages()` and `attributes()` methods:

```
protected function messages(): array
{
    return [
        'name.min' => 'The :attribute is too short (min :min characters)!',
    ];
}

protected function attributes(): array
{
    return [
        'email' => 'user email address',
    ];
}
```

A `ValidationException` is thrown if the data does not comply with these rules during instantiation or modification via a setter.

### Default Values

[](#default-values)

Override the `defaults()` method to define default values.

```
protected function defaults(): array
{
    return [
        'age' => 18,
        'status' => 'active',
    ];
}
```

### Casting

[](#casting)

The package supports the same cast types as Laravel's Eloquent models. It also **automatically infers** the cast type from the native PHP type of your properties.

```
class UserDto extends Dto
{
    protected int $age;           // Automatically cast to int
    protected bool $is_active;    // Automatically cast to bool
    protected Carbon $created_at; // Automatically cast to Carbon
    protected UserStatus $status; // Automatically cast to Backed Enum
    protected AddressDto $address;// Automatically cast to nested DTO
    protected Fluent $metadata;   // Automatically cast to Fluent
}
```

If you need more control, you can still override the `casts()` method. Explicit casts always take precedence over native type inference.

Supported types: `int`, `float`, `string`, `bool`, `array`, `object`, `date`, `datetime`, `immutable_date`, `immutable_datetime`, `decimal:x`, `json`, `encrypted`.

You can also cast properties to [Backed Enums](https://www.php.net/manual/en/language.enumerations.backed.php) or [Fluent](https://laravel.com/api/11.x/Illuminate/Support/Fluent.html) objects:

```
protected function casts(): array
{
    return [
        'status' => UserStatus::class,
    ];
}
```

You can also specify a custom format for date and datetime casts, which will be used when calling `toArray()`:

```
protected function casts(): array
{
    return [
        'created_at' => 'datetime:Y-m-d H:i',
        'birth_date' => 'date:d/m/Y',
    ];
}
```

### Magic Getters, Setters and Fluent Interface

[](#magic-getters-setters-and-fluent-interface)

You can access your properties via magic methods. Setters automatically apply validation and casting.

```
$dto->setName('Jane Doe'); // Setter
echo $dto->getName();      // Getter
```

The package also supports a fluent interface (methods with the same name as the property):

```
$dto->name('Jane Doe');    // Setter (returns $this)
echo $dto->name();         // Getter
```

### CamelCase / Snake\_case Support

[](#camelcase--snake_case-support)

If your properties are defined in `snake_case` in your class, you can access them in `camelCase` seamlessly.

```
/**
 * @property string $first_name
 *
 * @method string getFirstName()
 * @method self setFirstName(string $firstName)
 */
class UserDto extends Dto {
    protected string $first_name;
}

$dto = new UserDto(['first_name' => 'John']);

echo $dto->firstName;      // John
echo $dto->getFirstName(); // John
$dto->setFirstName('Jane');
```

### Array Conversion

[](#array-conversion)

The `toArray()` method returns all properties (public, protected, or private). It recursively handles nested DTOs. Dates are formatted according to their cast:

- `Y-m-d` for `date` and `immutable_date`
- `Y-m-d H:i:s` for `datetime` and `immutable_datetime` (MySQL format)

### Property Mapping

[](#property-mapping)

You can map property names to different keys when converting the DTO to an array using the `#[Map]` attribute or the `map()` method.

The `map()` method takes precedence over the attribute.

```
use Novius\LaravelDto\Dto;
use Novius\LaravelDto\Attributes\Map;

class UserDto extends Dto
{
    #[Map('dt-debut')]
    protected string $date_begin;

    protected string $date_end;

    protected function map(): array
    {
        return [
            'date_end' => 'dt-fin',
        ];
    }
}
```

### Configuration via Attributes

[](#configuration-via-attributes)

In addition to methods, you can use PHP attributes to configure your properties directly.

#### Validation Rules

[](#validation-rules)

Use the `#[Rules]` attribute to define validation rules.

```
use Novius\LaravelDto\Attributes\Rules;

class UserDto extends Dto
{
    #[Rules('required|string|min:3')]
    protected string $name;
}
```

#### Default Values

[](#default-values-1)

Use the `#[DefaultValue]` attribute to define default values.

```
use Novius\LaravelDto\Attributes\DefaultValue;

class UserDto extends Dto
{
    #[DefaultValue(18)]
    protected int $age;
}
```

#### Custom Casting

[](#custom-casting)

Use the `#[Cast]` attribute to define a custom cast type.

```
use Novius\LaravelDto\Attributes\Cast;

class UserDto extends Dto
{
    #[Cast('bool')]
    protected $is_admin;

    #[Cast('datetime:Y-m-d H:i')]
    protected Carbon $created_at;
}
```

**Note:** Methods (`rules()`, `defaults()`, `casts()`) always take precedence over attributes.

### Excluding Properties from DTO Mechanisms

[](#excluding-properties-from-dto-mechanisms)

You can use the `#[ExcludeFromDTO]` attribute to completely exclude a property from all DTO mechanisms (constructor instantiation, magic getters/setters, fluent interface, validation, and `toArray()` output).

This is useful for properties that you want to keep in the class for internal use only, without them being part of the Data Transfer Object's public data flow.

```
use Novius\LaravelDto\Dto;
use Novius\LaravelDto\Attributes\ExcludeFromDTO;

class UserDto extends Dto
{
    protected string $name;

    #[ExcludeFromDTO]
    protected string $internal_token;
}

// This will throw an InvalidArgumentException because internal_token is excluded
$dto = new UserDto(['name' => 'John', 'internal_token' => 'secret']);

// This is also forbidden
$dto = new UserDto(['name' => 'John']);
$dto->internal_token = 'secret'; // Throws InvalidArgumentException
```

Excluded properties are not present in the array representation:

```
$dto = new UserDto(['name' => 'John']);
print_r($dto->toArray());
// Output: ['name' => 'John']
```

Testing
-------

[](#testing)

The package uses [Pest](https://pestphp.com/) for testing.

```
composer test
```

Static Analysis
---------------

[](#static-analysis)

```
composer analyze
```

License
-------

[](#license)

This project is licensed under the AGPL-3.0-or-later License.

###  Health Score

43

—

FairBetter than 89% of packages

Maintenance85

Actively maintained with recent releases

Popularity15

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity54

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~2 days

Total

13

Last Release

81d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/341860?v=4)[Novius](/maintainers/novius)[@novius](https://github.com/novius)

---

Top Contributors

[![felixgilles](https://avatars.githubusercontent.com/u/900854?v=4)](https://github.com/felixgilles "felixgilles (22 commits)")

###  Code Quality

TestsPest

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/novius-laravel-dto/health.svg)

```
[![Health](https://phpackages.com/badges/novius-laravel-dto/health.svg)](https://phpackages.com/packages/novius-laravel-dto)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.3M347](/packages/psalm-plugin-laravel)[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

77922.3M186](/packages/laravel-mcp)[propaganistas/laravel-disposable-email

Disposable email validator

6023.0M7](/packages/propaganistas-laravel-disposable-email)[illuminate/pipeline

The Illuminate Pipeline package.

9349.2M291](/packages/illuminate-pipeline)[illuminate/pagination

The Illuminate Pagination package.

10534.1M1.1k](/packages/illuminate-pagination)[illuminate/redis

The Illuminate Redis package.

8314.6M388](/packages/illuminate-redis)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
