Weave 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

Simple Data Transfer Object Laravel Package

dragon-code/simple-data-transfer-object

dragon-code/simple-data-transfer-object offers a lightweight way to define typed data transfer objects in Laravel and PHP applications, helping you move structured data between layers with less boilerplate and clearer, more predictable code. Ideal for request payloads, API responses, and service bou...

View on GitHub
Deep Wiki
Context7

Getting Started

This is a tiny, framework-agnostic DTO helper rather than a full Laravel data layer. Treat it as a typed property bag for moving data across boundaries: request → DTO → action/service, job payload, or API response.

  1. Confirm the installed version and pin it. The package is archived, so avoid floating constraints:
    composer show dragon-code/simple-data-transfer-object
    
  2. Read the installed source and tests first. The package is small; the exact hydration/serialization API in your version matters. Start with:
    • vendor/dragon-code/simple-data-transfer-object/src/DataTransferObject.php
    • the package tests/README for fromArray(), from(), toArray(), nested DTO behavior, and property visibility expectations.
  3. Define a DTO with public typed properties and an explicit named constructor. Do not rely on magic mapping for production payloads:
    use DragonCode\SimpleDataTransferObject\DataTransferObject;
    
    final class CreateOrderData extends DataTransferObject
    {
        public int $customerId;
        /** @var array<int, array{sku: string, qty: int}> */
        public array $lines;
        public ?string $coupon = null;
    
        public static function fromValidated(array $input): self
        {
            $dto = new self();
            $dto->customerId = (int) $input['customer_id'];
            $dto->lines = array_map(
                fn (array $line): array => [
                    'sku' => (string) $line['sku'],
                    'qty' => (int) $line['qty'],
                ],
                $input['lines'] ?? []
            );
            $dto->coupon = $input['coupon'] ?? null;
    
            return $dto;
        }
    }
    
  4. First use case: in a Laravel controller, validate with a FormRequest, map $request->validated() into the DTO, and pass the DTO to an action or service. The action should not receive the request object or raw validated array.

Implementation Patterns

  • Use DTOs as layer contracts: controller/job/command maps input to DTO; service/action accepts DTO; persistence/HTTP layer converts back. This keeps array keys from leaking through the codebase.
  • Map explicitly at the edge: keep fromValidated(), fromModel(), or a dedicated mapper close to the DTO. Centralizing casts, defaults, and key renaming is more valuable than saving a few lines with generic hydration.
  • Keep DTOs immutable by convention: use public readonly properties on PHP 8.1+ where possible, avoid setters, and create a new DTO for updates. Public mutable properties are fine for tiny internal payloads, but they invite accidental changes.
  • Handle nested data deliberately: nested DTOs and arrays of DTOs are usually best mapped manually with array_map() plus a named constructor. Do not assume the package auto-hydrates nested objects, dates, enums, or collections unless you have verified it in the installed source.
  • Serialize at the boundary: call $dto->toArray() before logging, queueing, or JSON responses. Convert dates to ISO strings and backed enums to scalar values in your mapper/serializer rather than relying on json_encode($dto) unless the base class implements JsonSerializable.
  • Validate before hydration: use Laravel validation/FormRequests first, then map into the DTO. The DTO should enforce shape and types, not replace validation rules.
  • Be careful with queued jobs: passing a DTO to a job works for public properties, but queued payloads outlive code changes. For long-lived queues, serialize to an array or version the payload; avoid closures, resources, and package-specific internals.
  • Test round trips: assert both fromValidated() and toArray() for required fields, nullables, nested arrays, and type casts. A small DTO is easy to test; use that to compensate for the package’s low adoption.
  • Laravel integration is manual: no service provider or config is expected. Instantiate DTOs in controllers/actions/jobs; do not add container bindings just for DTOs.

Gotchas and Tips

  • Archived package risk: pin the exact version, keep it behind a project-level base class, and plan a migration path to plain readonly classes or a maintained DTO/data package. Do not make it the foundation of a shared domain model.
  • Uninitialized typed properties: if a mapper forgets a non-nullable property, accessing it throws an Error. Initialize nullable/default properties and test every required key.
  • Strict types and casts: assigning "1" to an int property fails under strict typing. Cast in the mapper ((int), (string), (bool)) instead of trusting request input.
  • Unknown keys: verify whether the installed base class ignores, rejects, or forwards unknown keys. Prefer explicit mapping so extra request fields cannot silently enter the DTO.
  • toArray() visibility: many simple DTO implementations serialize only public properties. Keep DTO state public or write a custom serializer; private/protected properties may disappear.
  • Null vs missing: use array_key_exists() when the distinction matters. $input['x'] ?? null collapses missing and null.
  • Dates, enums, and money: convert these at mapping time. Do not let raw Carbon, enum instances, or floats with currency semantics leak into serialized payloads.
  • No built-in validation or Laravel magic: validate with Laravel first, then map. Do not expect model casting, route-model binding, or resource transformation from this package.
  • Debugging: inspect $dto->toArray() and get_object_vars($dto); check for uninitialized properties and visibility. If hydration fails, compare the installed base class factory behavior with the tests.
  • Extension points: create a project BaseData extends DataTransferObject, add mapping traits or named constructors there, and keep package usage isolated. Never edit vendor code.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource