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

Models Laravel Package

spiral/models

Spiral DataEntity models package. Provides lightweight, type-safe data models/entities for your application with strong static analysis support (Psalm) and test coverage. Part of the Spiral ecosystem; MIT licensed.

View on GitHub
Deep Wiki
Context7

Getting Started

This package provides immutable, schema-aware data transfer objects (DTOs) with field mutators and reflection—ideal for enforcing strict data contracts in Laravel or standalone PHP apps. Though it originates from Spiral Framework (hence the spiral/models namespace), it’s framework-agnostic.

Start by installing via Composer:

composer require spiral/models

Define a model class extending Spiral\Models\Model and declare typed properties. Use the @fields annotation, native typed properties (PHP 8+), or the new schema commands (now decoupled from the entity) to define the schema. For v2.2.1+, schema definitions are managed separately via Spiral\Models\Commands\* for better modularity:

use Spiral\Models\Model;

/**
 * @property-read int $id
 * @property-read string $name
 */
class UserDTO extends Model
{
    // Schema is now defined externally via commands or config
    // Example: Use `Spiral\Models\Commands\DefineSchema` in a service provider
    public function __construct(int $id, string $name)
    {
        $this->id = $id;
        $this->name = $name;
    }
}

The first practical use case: validating and encapsulating API responses or database rows with immutable structure.


Implementation Patterns

  • DTO with Mutators: Implement custom logic in __set() or dedicated mutator methods (e.g., withName()), leveraging immutability via clone and __clone(). Use newInstance() for updates:
    $updated = $dto->newInstance(['name' => 'Updated']);
    
  • Schema Management: Define schemas externally using Spiral\Models\Commands\DefineSchema or via config. Example:
    // In a service provider
    DefineSchema::for(UserDTO::class)
        ->fields(['id', 'name'])
        ->types(['id' => 'int', 'name' => 'string']);
    
  • Reflection for Serialization: Use ModelReflection::from($dto) to inspect schema, generate JSON schema, or validate fields. Cache reflections for performance:
    $reflection = ModelReflection::from(UserDTO::class);
    $schema = $reflection->toJsonSchema();
    
  • Typed Arrays: Transform collections of DTOs using map() or collect():
    $users = UserDTO::fromArray($rawData)->map(fn ($dto) => $dto->withName(ucfirst($dto->name)));
    
  • Validation & Casting: Integrate with Laravel’s Validator by implementing ShouldValidate:
    class UserDTO extends Model implements ShouldValidate
    {
        public static function rules(): array
        {
            return ['name' => 'required|string'];
        }
    }
    
  • Extending Eloquent: Wrap Eloquent models via from(EloquentModel::class) to add behavior without modifying domain models.

Gotchas and Tips

  • Immutable by Design: Direct property assignment (e.g., $dto->name = 'new') fails. Use withName() or newInstance():
    $dto->newInstance(['name' => 'new']); // Correct
    
  • Schema Decoupling: In v2.2.1+, schemas are no longer embedded in the entity. Ensure schemas are defined before instantiating DTOs, or use lazy-loading via ModelReflection.
  • Field Typing: Enable strict_types=1 to catch type mismatches early. Mis-typed values may throw exceptions or fail silently.
  • Reflection Performance: Cache ModelReflection instances in a service provider or use dependency injection:
    $this->app->singleton(ModelReflection::class, fn () => ModelReflection::from(UserDTO::class));
    
  • Missing Schema Definitions: Without explicit schema commands or annotations, field introspection will fail. Prefer typed properties (PHP 8+) or DefineSchema for clarity.
  • Deprecation Risk: Last major update in 2023, but the package remains stable. For new projects, evaluate alternatives like spatie/data-transfer-object if active maintenance is critical. The decoupled schema system in v2.2.1 improves modularity but may require refactoring existing 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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
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
twbs/bootstrap4
php-http/client-implementation
phpcr/phpcr-implementation
cucumber/gherkin-monorepo
haydenpierce/class-finder
psr/simple-cache-implementation
uri-template/tests