Migration from Spatie Laravel Data
Complete guide to migrating from Spatie Laravel Data to SimpleDTO.
Why Migrate?
Section titled “Why Migrate?”SimpleDTO provides a smooth migration path from Spatie Laravel Data:
- Similar API - Familiar methods and patterns
- More Features - 18 conditional attributes for fine-grained control
- Framework Independent - Works with Laravel, Symfony, and plain PHP
- Backward Compatible - Easy to migrate incrementally
- Validation Caching - Built-in caching for better performance
Feature Comparison
Section titled “Feature Comparison”| Feature | Spatie Data | SimpleDTO |
|---|---|---|
| Framework Support | Laravel only | Laravel, Symfony, PHP |
| TypeScript Generation | ✅ Yes | ✅ Yes |
| Lazy Properties | ✅ Yes | ✅ Yes |
| Computed Properties | ✅ Yes | ✅ Yes |
| Collections | ✅ Yes | ✅ Yes |
| Validation Caching | ❌ No | ✅ Yes |
| Conditional Attributes | 2 attributes | 18 attributes |
Automated Migration
Section titled “Automated Migration”Using Artisan Command (Recommended)
Section titled “Using Artisan Command (Recommended)”The easiest way to migrate is using the built-in Artisan command:
# Migrate all Spatie Data classes in app/Dataphp artisan dto:migrate-spatie
# Migrate specific directoryphp artisan dto:migrate-spatie --path=app/Data/Api
# Dry run (preview changes without modifying files)php artisan dto:migrate-spatie --dry-run
# Backup files before migrationphp artisan dto:migrate-spatie --backupThe command will:
- Find all Spatie Data classes
- Replace base class (
Data→SimpleDTO) - Update namespace imports
- Add
readonlyto properties - Update attribute namespaces
- Create backup files (if
--backupflag is used)
Manual Migration Steps
Section titled “Manual Migration Steps”If you prefer manual migration:
Step 1: Install SimpleDTO
Section titled “Step 1: Install SimpleDTO”composer require event4u/data-helpersStep 2: Update Base Class
Section titled “Step 2: Update Base Class”Before (Spatie):
use Spatie\LaravelData\Data;
class UserData extends Data{ public function __construct( public string $name, public string $email, ) {}}After (SimpleDTO):
use event4u\DataHelpers\SimpleDTO\SimpleDTO;
class UserDTO extends SimpleDTO{ public function __construct( public readonly string $name, public readonly string $email, ) {}}Step 3: Update Attributes
Section titled “Step 3: Update Attributes”Before (Spatie):
use Spatie\LaravelData\Attributes\Validation\Required;use Spatie\LaravelData\Attributes\Validation\Email;
class UserData extends Data{ public function __construct( #[Required] public string $name,
#[Required, Email] public string $email, ) {}}After (SimpleDTO):
use event4u\DataHelpers\SimpleDTO\Attributes\Required;use event4u\DataHelpers\SimpleDTO\Attributes\Email;
class UserDTO extends SimpleDTO{ public function __construct( #[Required] public readonly string $name,
#[Required, Email] public readonly string $email, ) {}}API Mapping
Section titled “API Mapping”Creation Methods
Section titled “Creation Methods”| Spatie Data | SimpleDTO | Notes |
|---|---|---|
Data::from() | SimpleDTO::fromArray() | Same functionality |
Data::collect() | DataCollection::make() | Same functionality |
Data::validateAndCreate() | SimpleDTO::validateAndCreate() | Same functionality |
Serialization Methods
Section titled “Serialization Methods”| Spatie Data | SimpleDTO | Notes |
|---|---|---|
toArray() | toArray() | Same |
toJson() | toJson() | Same |
toXml() | toXml() | Same |
Conditional Properties
Section titled “Conditional Properties”| Spatie Data | SimpleDTO | Notes |
|---|---|---|
#[Hidden] | #[Hidden] | Same |
#[Computed] | #[Computed] | Same |
#[Lazy] | #[Lazy] | Same |
#[WithCast] | #[Cast] | Different name |
Migration Examples
Section titled “Migration Examples”Example 1: Basic DTO
Section titled “Example 1: Basic DTO”Before (Spatie):
use Spatie\LaravelData\Data;
class UserData extends Data{ public function __construct( public int $id, public string $name, public string $email, ) {}}
$user = UserData::from([ 'id' => 1, 'name' => 'John Doe', 'email' => 'john@example.com',]);After (SimpleDTO):
use event4u\DataHelpers\SimpleDTO\SimpleDTO;
class UserDTO extends SimpleDTO{ public function __construct( public readonly int $id, public readonly string $name, public readonly string $email, ) {}}
$user = UserDTO::fromArray([ 'id' => 1, 'name' => 'John Doe', 'email' => 'john@example.com',]);Example 2: Validation
Section titled “Example 2: Validation”Before (Spatie):
use Spatie\LaravelData\Data;use Spatie\LaravelData\Attributes\Validation\Required;use Spatie\LaravelData\Attributes\Validation\Email;
class CreateUserData extends Data{ public function __construct( #[Required] public string $name,
#[Required, Email] public string $email, ) {}}After (SimpleDTO):
use event4u\DataHelpers\SimpleDTO\SimpleDTO;use event4u\DataHelpers\SimpleDTO\Attributes\Required;use event4u\DataHelpers\SimpleDTO\Attributes\Email;
class CreateUserDTO extends SimpleDTO{ public function __construct( #[Required] public readonly string $name,
#[Required, Email] public readonly string $email, ) {}}Example 3: Collections
Section titled “Example 3: Collections”Before (Spatie):
use Spatie\LaravelData\DataCollection;
$users = UserData::collect($usersArray);After (SimpleDTO):
use event4u\DataHelpers\SimpleDTO\DataCollection;
$users = DataCollection::make($usersArray, UserDTO::class);New Features in SimpleDTO
Section titled “New Features in SimpleDTO”More Conditional Attributes
Section titled “More Conditional Attributes”SimpleDTO has 18 conditional attributes for fine-grained control:
class UserDTO extends SimpleDTO{ public function __construct( public readonly string $name,
// Authentication-based #[WhenAuth] public readonly ?string $email = null,
#[WhenGuest] public readonly ?string $publicProfile = null,
// Permission-based #[WhenCan('view-sensitive-data')] public readonly ?string $ssn = null,
// Role-based #[WhenRole('admin')] public readonly ?array $adminPanel = null,
// Value-based #[WhenValue('status', 'active')] public readonly ?string $activeFeatures = null, ) {}}Validation Caching
Section titled “Validation Caching”# Cache validation rules for better performancephp artisan dto:cacheFramework Independence
Section titled “Framework Independence”// Works in Laravel$dto = UserDTO::fromModel($user);
// Works in Symfony$dto = UserDTO::fromEntity($user);
// Works in plain PHP$dto = UserDTO::fromArray($data);Migration Checklist
Section titled “Migration Checklist”Before Migration
Section titled “Before Migration”- Review current Spatie Data usage
- Identify custom casts and transformers
- Document conditional logic
- Backup codebase
During Migration
Section titled “During Migration”- Install SimpleDTO
- Run
dto:migrate-spatiecommand or migrate manually - Update method calls if needed
- Test thoroughly
After Migration
Section titled “After Migration”- Remove Spatie Data package
- Update tests
- Generate TypeScript types
- Cache validation rules
Troubleshooting
Section titled “Troubleshooting”Issue: Properties are not readonly
Section titled “Issue: Properties are not readonly”Solution: Add readonly keyword to all properties:
// Beforepublic string $name;
// Afterpublic readonly string $name;Issue: Validation not working
Section titled “Issue: Validation not working”Solution: Use validateAndCreate() instead of fromArray():
// This validates$dto = UserDTO::validateAndCreate($data);
// This doesn't validate$dto = UserDTO::fromArray($data);Issue: Collections not working
Section titled “Issue: Collections not working”Solution: Use DataCollection::make() with class name:
// Before (Spatie)$users = UserData::collect($data);
// After (SimpleDTO)$users = DataCollection::make($data, UserDTO::class);Next Steps
Section titled “Next Steps”- Artisan Commands - Learn about all available commands
- Validation - Explore validation features
- Conditional Properties - Use advanced conditional logic
- Performance - Optimize your DTOs