Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Data Transfer Object Laravel Package

spatie/data-transfer-object

PHP 8+ data transfer objects with “batteries included”: map and cast input arrays into typed DTOs, validate via attributes, and handle nested objects/collections. Note: package is deprecated; consider spatie/laravel-data or cuyz/valinor.

View on GitHub
Deep Wiki
Context7

Getting Started

Begin by installing the package:

composer require spatie/data-transfer-object

Create a basic DTO by extending Spatie\DataTransferObject\DataTransferObject. Start with simple scalar properties, then gradually introduce nested DTOs, collections, and casters. The package uses PHP 8+ attributes (#[...]) for configuration, so ensure your environment supports attributes. The core use case is converting raw arrays (e.g., API responses, database results) into strongly-typed objects — ideal for API payloads or service layer communication. The simplest entry point is using named arguments to instantiate a DTO, leveraging PHP’s named parameter syntax for clarity.

Implementation Patterns

  • Nested DTOs & Collections: Define typed properties for nested DTOs or arrays of DTOs. The package automatically converts arrays to DTOs or collections when type hints match known DTO classes. For complex structures, use #[CastWith(...)] to specify custom caster logic.
  • Custom Caster Classes: Implement Spatie\DataTransferObject\Caster to transform non-standard types (e.g., enums, value objects,DateTimeImmutable). Use DefaultCast attributes on abstract base DTOs to apply casters globally for certain types.
  • Property Mapping: Use #[MapFrom('source.key')] to rename or destructure input data (including dot-notation paths like user.address.city). Combine with #[MapTo(...)] when serializing back to arrays (e.g., for API responses or storage).
  • Validation via Attributes: Implement custom attributes that implement Spatie\DataTransferObject\Validator to validate values during construction — similar to how #[NumberBetween(...)] is used in the README. This keeps validation declarative and close to property definitions.
  • Immutability & Cloning: Treat DTOs as immutable by convention; use the clone() method to create modified copies without mutating the original. Avoid direct property mutation to maintain safety across threads or middleware.
  • Helper Methods: Use only(), except(), and toArray() for controlled serialization. Prefer toArray() over all() for nested DTO-to-array conversion.

Gotchas and Tips

  • ⚠️ Package is archived: As of 2022-09-16, this package is deprecated. Migrate to spatie/laravel-data (if using Laravel) or cuyz/valinor (PSR-7/17-aligned, modern PHP). Continuing to use this package increases long-term maintenance risk.
  • Strict vs. Flexible: DTOs are flexible (ignores unknown keys) by default. Use #[Strict] to enforce explicit property declarations — essential for catching typos or schema mismatches in APIs.
  • PHP Version: Only supports PHP 8+ (^8.0). v2 exists for PHP 7 but lacks modern features (attributes, union types).
  • Collections: Avoid the legacy DataTransferObjectCollection. Implement custom collections or use Laravel’s Collection with a tailored ArrayCaster for type-safe iteration and operations.
  • Caster Argument Ordering: Caster constructors receive the property’s expected type(s) first, then any additional arguments passed in #[CastWith(..., arg: value)]. Verify this order when debugging cast failures.
  • Validation Errors: Validation attributes return ValidationResult but do not stop execution by default. You must check $dto->isValid() or inspect $dto->getValidationErrors() manually if using validators.
  • Testing: DTO construction is easy to unit-test — just assert property values post-instantiation with known inputs. Use #[MapFrom] edge cases to validate flexible deserialization.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport