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 Model Laravel Package

zero-to-prod/data-model

Reflection-based PHP data models that hydrate from arrays/objects via a single from() call. Use attributes to centralize casting, validation, defaults, required/nullable rules, and assignment behavior—ideal for external data like APIs, DB rows, and user input.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Strong alignment with Laravel’s DTO patterns: The package excels at replacing manual DTO hydration (e.g., new User($data)) with type-safe, declarative alternatives. This directly addresses Laravel’s common pain points in API responses, form requests, and database hydration.
  • Complementary to Laravel’s ecosystem: Works seamlessly with Laravel’s validation (via #[Describe] rules), Eloquent models (recursive hydration), and API contracts (e.g., #[Describe('required')] for FormRequest validation).
  • Reduces boilerplate: Eliminates repetitive isset(), array_get(), and constructor logic, aligning with Laravel’s philosophy of "convention over configuration" while adding explicit control.

Integration Feasibility

  • Minimal friction: Requires only use DataModel; and #[Describe] attributes—no base classes, interfaces, or complex setup. Laravel’s attribute support (PHP 8+) ensures zero compatibility issues.
  • Laravel-specific extensions: The Laravel Validation example in the README demonstrates how #[Describe] rules can directly map to Laravel’s validation rules (e.g., required, nullable), reducing duplication between DTOs and FormRequest classes.
  • Recursive hydration: Automatically handles nested objects (e.g., User with Address), which is critical for Laravel’s Eloquent relationships and API payloads.

Technical Risk

  • Attribute overhead: While #[Describe] is powerful, overuse could clutter classes. Mitigation: Use sparingly for complex transformations; default to type hints for simple cases.
  • Performance: Reflection-based hydration adds minor overhead. Benchmark critical paths (e.g., API response parsing) to validate impact. The package’s design prioritizes clarity over micro-optimizations.
  • Laravel-specific edge cases:
    • Eloquent models: Hydration from database arrays may conflict with Eloquent’s fillable/guarded. Solution: Use via to delegate to Eloquent’s fill() or create().
    • Service containers: If using assign or via with container-bound classes, ensure dependencies are resolvable. Test with Laravel’s bind() or make().
  • Backward compatibility: The package is actively maintained (releases in 2026), but Laravel’s evolving attribute system (e.g., PHP 8.2+) could require minor adjustments.

Key Questions

  1. Adoption scope:
    • Will this replace all DTO hydration (e.g., API responses, form requests) or only complex cases?
    • How will it interact with existing FormRequest validation logic? (Potential: Merge #[Describe] rules into rules() array.)
  2. Testing strategy:
    • How will we verify #[Describe] configurations? (Suggestion: Static analysis tools like PHPStan or custom tests for attribute validation.)
  3. Performance:
    • Are there hot paths (e.g., API endpoints) where reflection overhead is unacceptable? If so, consider caching ReflectionProperty instances.
  4. Team buy-in:
    • Will developers adopt #[Describe] for new DTOs, or will it remain optional? (Suggestion: Enforce via a custom PHPCS rule or Laravel policy.)
  5. Laravel-specific extensions:
    • Should we create a LaravelDataModel trait to integrate with Eloquent, validation, or API resources? (Example: Auto-register #[Describe] rules in FormRequest::rules().)

Integration Approach

Stack Fit

  • Laravel core: Ideal for:
    • API resources: Replace Resource::toArray() with DataModel::from($data) for type-safe responses.
    • Form requests: Use #[Describe] to define validation rules, eliminating duplicate rules() arrays.
    • Eloquent hydration: Hydrate models from arrays (e.g., API payloads) without manual fill() calls.
    • Service layers: Replace constructor injection with DataModel::from($request->all()) for cleaner service boundaries.
  • Third-party packages:
    • Spatie Laravel Data: Could be a drop-in replacement for simpler use cases.
    • Laravel Serializable: Complementary for API serialization/deserialization.
  • Non-Laravel PHP: Works anywhere PHP 8+ runs, but Laravel-specific features (e.g., validation integration) require custom glue code.

Migration Path

  1. Pilot phase:
    • Start with one high-impact DTO (e.g., API request/response) to validate benefits.
    • Example: Replace a CreateUserRequest with #[Describe] attributes for validation.
  2. Incremental adoption:
    • Step 1: Use DataModel for simple hydration (e.g., User::from($request->all())).
    • Step 2: Add #[Describe] for validation/casting (e.g., #[Describe(['required', 'cast' => 'strtoupper'])]).
    • Step 3: Replace manual fill() calls with recursive hydration for nested objects.
  3. Tooling integration:
    • Create a custom Laravel rule to auto-generate FormRequest::rules() from #[Describe] attributes.
    • Example:
      // In a FormRequest:
      #[Describe(['required', 'min' => 18])]
      public int $age;
      
      → Automatically maps to rules(['age' => 'required|min:18']).
  4. Deprecation strategy:
    • Gradually phase out manual DTO constructors in favor of DataModel::from().
    • Use PHPStan to detect unused constructors and encourage migration.

Compatibility

  • Laravel versions: Tested with PHP 8.1+ (per README). Ensure compatibility with Laravel 10/11’s attribute system.
  • Existing code:
    • Backward compatibility: DataModel::from() won’t break existing constructors (though constructors may become redundant).
    • Validation libraries: Integrate with Laravel’s validation (e.g., #[Describe]rules()) or third-party libraries like Respect/Validation.
  • Database layers:
    • Eloquent: Use via to delegate to Model::fill() or Model::create() for database hydration.
    • Query builders: Hydrate collections with Collection::map(fn($item) => User::from($item)).

Sequencing

  1. Phase 1: API Layer (High visibility, low risk):
    • Replace API request/response DTOs with DataModel.
    • Example: UserResourceUserDataModel with #[Describe] for serialization.
  2. Phase 2: Form Handling (Validation synergy):
    • Migrate FormRequest classes to use #[Describe] for validation.
    • Automate rule generation via a custom macro or package.
  3. Phase 3: Service Layer (Internal DTOs):
    • Replace manual object assembly in services with DataModel::from().
  4. Phase 4: Database Hydration (Highest risk):
    • Replace Model::fill() with DataModel::from() for API-driven model creation.
    • Test thoroughly for edge cases (e.g., mass assignment, timestamps).

Operational Impact

Maintenance

  • Pros:
    • Centralized logic: All hydration rules are colocated in #[Describe] attributes, reducing scattered validation/transformation code.
    • Self-documenting: Attributes serve as executable documentation (e.g., #[Describe(['cast' => 'strtoupper'])] clarifies intent).
    • Reduced boilerplate: Less manual code means fewer places for bugs to hide.
  • Cons:
    • Attribute sprawl: Overuse of #[Describe] could make classes harder to read. Mitigation: Use for complex logic only; default to type hints.
    • Debugging complexity: Nested pre/post hooks or custom via methods may require deeper debugging. Solution: Add logging or use Xdebug for complex flows.
  • Tooling:
    • Static analysis: PHPStan/Psalm can verify #[Describe] configurations at development time.
    • IDE support: Modern IDEs (PHPStorm, VSCode) will autocomplete attribute keys and show docblocks.

Support

  • Developer onboarding:
    • Training: Document the migration path and provide examples for common use cases (e.g., API responses, form validation).
    • Cheat sheet: Summarize #[Describe] keys and their Laravel equivalents (e.g., requiredrequired|sometimes).
  • Common issues:
    • Missing properties: Educate teams on required vs. nullable vs. default.
    • Type mismatches: Use PHPStan to catch type errors early.
    • Recursive hydration failures: Document how to handle circular references (e.g., UserOrder).
  • Error handling:
    • Customize PropertyRequiredException messages for user-friendly API errors.
    • Example:
      try {
          $user = User::from($request->all());
      } catch (PropertyRequired
      
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.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope