Product Decisions This Supports
- Architecture bet: typed DTOs vs. associative arrays. This package is the enabler for a "no arrays past the boundary" policy — inbound payloads, config, queue messages, and third-party API responses get hydrated into explicit objects with real types. Adopting it is a decision to standardize that pattern across a codebase rather than re-litigating it per feature.
- Build vs. buy on the mapping layer. Teams routinely hand-roll
array_map + constructor plumbing + (int) casts per integration. This package replaces that with a declarative, tested implementation (~1 dependency, BSD-3-Clause, no copyleft exposure). The buy decision is cheap; the real cost is the migration and the standard-setting.
- Integration surface roadmap. Every new external integration (webhooks, partner APIs, payment providers, ERP sync) adds an array→object boundary. Choosing a hydrator now sets the cost curve for integration #2 through #20; choosing ad hoc casting sets a per-integration tax.
- Feature velocity on request handling. Form/API input → DTO → domain service is the highest-volume path in most Laravel apps. Type casting plus nested mapping plus container-resolved constructor dependencies means adding a field is a one-line DTO change instead of edits across controller, validator, and service.
- Queue/event contract evolution. Message deserialization into typed objects with defaults makes versioned event schemas tractable — new optional fields, renamed keys via mapping, type drift between producers.
- Test and fixture strategy. Hydration gives a single canonical way to build domain objects in tests and seeders, reducing fixture drift and "works in test, fails on real payload" defects.
- Explicit non-decision: this is not a validator and not a full serializer. If roadmap pressure is toward schema validation and OpenAPI-generated contracts, the decision belongs with
spatie/laravel-data, cuyz/valinor, or symfony/serializer — not here.
When to Consider This Package
Consider it when:
- You have a meaningful number of array→object boundaries (roughly: more than a handful of integrations, or a DTO layer already emerging organically).
- You want nested mapping — arrays inside arrays becoming typed child objects — without writing recursive mappers.
- Constructor dependencies should be resolved from a PSR-11 container while the rest of the object is populated from input. This is the differentiator versus most hydrators.
- You want type coercion handled centrally (
"42" → 42, date strings → DateTimeImmutable) with one behavior to reason about, not per-call-site casts.
- You are comfortable with attribute/annotation-driven metadata and plain PHP objects (no Active Record, no magic properties).
- Dependency hygiene matters: small surface, permissive license, framework-agnostic, easy to wrap behind your own interface.
Look elsewhere when:
- Validation is the actual requirement. Hydration ≠ validation. Pair with
yiisoft/hydrator-validator or use spatie/laravel-data, which bundles validation, casts, and Laravel-native ergonomics.
- You want first-class Laravel DX — FormRequest integration, artisan generators, Eloquent-aware casts, a large recipe corpus.
spatie/laravel-data wins on ecosystem fit; this package is Yii-origin and will need a service-provider wrapper.
- Ecosystem confidence is a hard requirement. ~34 stars and a single-vendor maintainer is a real signal. If your org mandates active community support, SLA-backed dependencies, or broad Stack Overflow coverage, this fails procurement review regardless of technical merit.
- You need a full serializer (round-trip, normalization groups, format adapters, circular-reference strategies). Use
symfony/serializer or cuyz/valinor.
- Hot-path performance is critical (per-request hydration of large collections in a tight loop). Benchmark before committing; reflection-based hydration has a cost profile you should measure against hand-written mapping.
- You already have a working mapping convention and the migration would be cosmetic. Standardizing for its own sake is not a business case.
Adoption gate: pilot on one integration behind a HydratorInterface adapter, measure LOC removed, defect rate on payload handling, and added latency, then decide on broader rollout.
How to Pitch It (Stakeholders)
For executives (30 seconds): We repeatedly write the same fragile code to turn incoming JSON, config, and queue messages into objects our application can trust. This package replaces that with a small, permissively licensed, framework-agnostic library that does it consistently and is easy to remove later. Low cost, low lock-in, modest upside: fewer data-shape bugs and faster delivery on every new integration. The caveat is community size — mitigation is a contained pilot behind our own interface, so the downside is capped at a few days of work.
For engineering leadership: It solves a narrow, real problem well — array→typed-object hydration with casting, nested mapping, and PSR-11 dependency resolution in constructors. That last capability is the reason to prefer it over hand-rolled mappers or lighter libraries. It is not a validator and not a serializer; budget accordingly. Integration in Laravel is a container binding and a thin adapter, not a rewrite.
For the engineering team: Wrap it. Define one internal hydration contract, bind this as the default implementation, and keep call sites unaware. That gives us the ergonomics now and a one-file swap if the project stalls or a better fit appears. Pair with a validator at the boundary; do not let hydration become implicit validation. Benchmark on the largest payload path before rollout, and document the type-coercion rules — silent coercion is the most likely source of "surprising" production behavior.