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

Hydrator Laravel Package

yiisoft/hydrator

Yii Hydrator populates typed objects from arrays and other input using attributes and property mapping. It handles type casting, nested hydration, and dependency injection, offering PHP and Laravel apps a fast, flexible alternative to manual DTO construction.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

yiisoft/hydrator is a framework-agnostic object hydrator from the Yii3 ecosystem, not a Laravel package. It solves a real gap in Laravel: turning untyped input (request payloads, queue messages, webhook bodies, third-party API responses) into typed, constructor-validated objects with attribute-driven mapping, type casting, and dependency resolution. Laravel's native equivalents are Eloquent fill() (array-oriented, weak typing, tied to models) and Form Requests (validation, not construction). So the package is additive, not a replacement for anything the framework already does well.

Its design is a two-stage pipeline: reflection builds a hydration plan per class, then handlers apply casting/mapping and resolve constructor dependencies from a PSR-11 container. That plan-caching architecture is the right shape for production use, and it is the main reason to consider it over hand-rolled fromArray() factories.

The honest framing for the business: this is a component, not a platform bet. It is competitive in concept with spatie/laravel-data, which is Laravel-native, has vastly larger adoption, and integrates with validation, resources, and Eloquent out of the box. Choosing yiisoft/hydrator means choosing a smaller, Yii-flavored dependency in exchange for a leaner, container-driven core and no Laravel coupling in the domain layer. That trade is defensible only if we isolate it behind our own interface.

Integration feasibility

High, with caveats. The integration surface is small and well-bounded:

  • Laravel's Illuminate\Container\Container already implements Psr\Container\ContainerInterface, so dependency resolution works by binding the app instance directly — no adapter needed.
  • Plan caching expects PSR-16 simple cache. Laravel's cache repository implements Psr\SimpleCache\CacheInterface, so a one-line binding is sufficient.
  • PHP and framework version requirements (8.1+, Laravel 10/11/12) line up with our supported matrix.
  • Registration is a single service provider that binds HydratorInterface as a singleton with our handler set and cache.

The friction is configuration and semantics, not plumbing. Type-casting behavior (nullables, enums, DateTimeImmutable, union types, nested arrays of DTOs) will not match Laravel's Validation/Cast semantics exactly, so parity must be proven with contract tests rather than assumed.

Technical risk

  • Maturity and bus factor (medium-high). 34 stars, single-vendor maintenance, Yii3 release cadence. Pre-1.x-style BC churn is plausible. Mitigation: pin exact versions and depend on our façade, never on the package API directly in application code.
  • Adoption risk (medium). Sparse Laravel-side documentation and examples; the docs assume Yii conventions. Our team will be trailblazing, which translates to schedule risk, not just code risk.
  • Error-model mismatch (medium). Hydration failures throw package exceptions, not ValidationException, so Laravel will not automatically produce 422 JSON responses. Unhandled, these become 500s in production. An exception-mapping layer is mandatory.
  • Mass-assignment exposure (medium). The hydrator will populate whatever the plan allows. Without explicit per-DTO allowlists or readonly DTOs, this reintroduces the vulnerability class Laravel's $fillable was designed to prevent.
  • Cache correctness (medium). A stale plan cache after a DTO shape change is a production-breaking failure mode that will not appear in local or CI runs unless cache behavior is exercised.
  • Opportunity score (low, 5.03). As a product opportunity — building on or around this package — the signal is weak. As an internal utility, the calculus is different and driven by the façade's cost, which is small.

Key questions

  1. What is the project's BC policy and release cadence, and who is the named maintainer?
  2. Does plan caching support a shared, versioned cache namespace, or must we key/flush manually on deploy?
  3. How are union types, intersection types, backed enums, and nested collections of DTOs handled?
  4. Can constructor parameters be resolved contextually (per-request values) versus statically from the container?
  5. What is the cold-start cost per class on a cache miss, and is the plan serializable across PHP versions?
  6. Is there a supported extension point for custom type casters and validation hooks?

Integration Approach

Stack fit

Laravel 10/11/12 on PHP 8.1+ via Composer. The package sits in the inbound boundary layer: HTTP payloads, console command arguments, queue job payloads, and third-party API responses. It should not touch Eloquent models or the persistence layer. The domain layer receives typed DTOs; the framework layer owns the mapping.

Migration path

Adopt incrementally and in one direction only — reads in, never writes out.

  1. Spike (1 week). Install, build a HydratorServiceProvider, hydrate one representative DTO exercising a nested object, an enum, a DateTimeImmutable, a nullable, and a collection. Benchmark cold and warm paths.
  2. Façade. Define an internal DtoHydrator interface and implement it once against the package. Every call site depends on our interface. This caps the blast radius of an upstream BC break or a later swap to spatie/laravel-data.
  3. Pilot. Apply to one or two endpoints with no persistence side effects — webhook ingestion is the ideal first target because the input is untrusted, external, and schema-stable.
  4. Broaden. Extend to console/queue payloads, then third-party API clients.
  5. Do not migrate existing Form Requests or Eloquent mass assignment. Coexistence is the goal; a repo-wide rewrite is not justified by a 34-star dependency.

Compatibility

  • PSR-11: satisfied natively by the Laravel container.
  • PSR-16: satisfied by Illuminate\Cache\Repository; bind an explicit cache store, not the array driver.
  • Composer: pin to a minor version and add composer outdated monitoring for the yiisoft/* namespace.
  • Attribute-based mapping requires PHP 8 attributes — already our floor.

Sequencing

Land the service provider and façade first, then the exception mapper, then contract tests, then the pilot endpoint. Do not sequence the pilot before the exception mapper: the fastest way to lose stakeholder confidence is a payload-validation failure surfacing as a 500 in a demo.

Operational Impact

Maintenance

Low ongoing code maintenance, moderate ongoing vigilance. The dependency tree is shallow and the license (BSD-3-Clause) is permissive and commercially safe. The real maintenance cost is monitoring an upstream with a small contributor base and no Laravel-community pressure to preserve behavior we depend on. The façade converts an upstream breaking change from an incident into a scheduled task; without it, this package is a standing liability.

Support

No first-line vendor support. Community channels are Yii-oriented, so our team is effectively the support tier. Budget an internal runbook covering service-provider wiring, cache configuration, custom casters, and the exception-mapping table. Designate one engineer as owner; a package this small has no organizational redundancy by default.

Scaling

Steady-state cost is low only if the plan cache is persistent and shared. With the array driver — the path of least resistance and what a naive integration will produce — every request rebuilds plans via reflection, converting a cheap operation into a per-request tax that scales linearly with traffic and DTO count. In a multi-node deployment this must be a shared store (Redis or similar), keyed by application build version. Cold-start after deploy is a real, measurable latency bump; the deploy pipeline should warm the cache for hot DTOs if p99 matters.

Failure modes

  • Stale plan cache after a DTO refactor. Highest-severity risk: silent in staging, hard failure in production, and invisible locally. Mitigate with build-versioned cache keys and a flush-on-deploy step.
  • Unmapped hydration exceptions. Malformed input produces 500s instead of 422s, polluting error budgets and paging on-call for what is a client error.
  • Silent mis-casting. Coercion differences (string-to-bool, empty-string-to-null, numeric strings to enums) create quietly wrong domain objects. This is worse than a crash because it corrupts downstream state.
  • Unresolvable constructor dependencies. A newly added service parameter that isn't bound produces container NotFoundException at hydration time, not at boot — a runtime landmine introduced by an unrelated refactor.
  • Over-permissive population. Missing allowlists allow clients to set fields they should not.

Ramp-up

A mid-level Laravel developer reaches productivity in roughly one to three days; the concepts (plan-then-apply, attribute mapping, DTO-first design) are unfamiliar but not difficult. The genuine ramp-up cost is conceptual, not syntactic: the team must unlearn active-record instincts and accept that DTOs are constructed, not filled. Budget one sprint-week end to end for the service provider, façade, exception mapper, contract tests, and documentation — and treat that week as the real cost of adoption, since the integration code outlives any single version of the package.

Recommendation

Proceed as a bounded pilot, not a platform decision. The technical fit is genuine and the integration cost is modest, but 34 stars, single-vendor maintenance, and a 5.03 opportunity score argue against making this a load-bearing dependency across the codebase. The façade is the deciding factor: with it, switching costs stay low and the package is an implementation detail; without it, we have adopted a small upstream's roadmap as our own.

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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle