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

Yin Laravel Package

woohoolabs/yin

PSR-7–compatible PHP framework for building JSON:API servers. Provides documents, resources, hydrators, request/response validation, pagination, relationship handling, content negotiation, middleware support, and custom serialization/deserialization.

View on GitHub
Deep Wiki
Context7

Getting Started

Install via Composer:

composer require woohoolabs/yin

Publish the config (optional):

php artisan vendor:publish --provider="Woohoolabs\Yin\YinServiceProvider"

First Use Case: Validate and hydrate a domain object from incoming request data:

use Woohoolabs\Yin\Hydrator;
use App\Domain\Objects\User;

$hydrator = app(Hydrator::class);
$user = $hydrator->hydrate(User::class, $request->all(), [
    'validate' => true, // New in 4.3.0: Enables validation of hydrated object
]);

Key files to review:

  • config/yin.php (for configuration options like omitDataWhenNotIncluded)
  • app/Domain/Objects/ (your domain objects with validation rules)

Implementation Patterns

Core Workflow

  1. Hydration with Validation (New in 4.3.0):

    $hydrator->hydrate(User::class, $data, [
        'validate' => true, // Triggers validation via domain object rules
        'omitDataWhenNotIncluded' => true, // Preserves existing behavior
    ]);
    
    • Automatically validates against domain object rules (e.g., use Illuminate\Contracts\Validation\Validatable).
  2. API Response Handling:

    $responseData = $hydrator->hydrate(User::class, $data, [
        'omitDataWhenNotIncluded' => true, // Fixes #103: Ensures omitted fields don't appear in response
    ])->toArray();
    
  3. Integration with Laravel Controllers:

    public function store(Request $request, Hydrator $hydrator) {
        $user = $hydrator->hydrate(User::class, $request->validated(), [
            'validate' => true, // Re-validates even if request validation passed
        ]);
        return response()->json($user);
    }
    

Common Patterns

  • Domain Object Structure:

    class User implements Validatable {
        use ValidatesWhenHydrated; // Optional trait for validation rules
    
        public function rules() {
            return [
                'email' => 'required|email',
                'password' => 'nullable|min:8',
            ];
        }
    }
    
  • Partial Updates:

    $hydrator->hydrate(User::class, ['email' => 'new@example.com'], [
        'partial' => true, // Only updates specified fields
    ]);
    

Gotchas and Tips

Pitfalls

  1. Validation Conflicts:

    • If using both Laravel request validation and validate: true in hydrator, the hydrator’s validation will run after request validation. Use validate: false in hydrator if you want to skip it.
  2. omitDataWhenNotIncluded Quirk (Fixed in 4.3.0):

    • Previously, this option could leave null values in the response for omitted fields. Now it completely omits them (e.g., ['email' => null] becomes []).
    • Tip: Test edge cases like ['email' => null] to ensure expected behavior.
  3. Performance:

    • Hydration + validation adds overhead. Cache the hydrator instance:
      $hydrator = app(Hydrator::class); // Reuse this instance
      

Debugging Tips

  • Validation Errors:

    try {
        $user = $hydrator->hydrate(User::class, $data, ['validate' => true]);
    } catch (ValidationException $e) {
        return response()->json($e->errors(), 422);
    }
    
  • Inspect Hydrated Data:

    $hydrator->hydrate(User::class, $data, [
        'debug' => true, // Logs raw data and validation rules (use in development only)
    ]);
    

Extension Points

  1. Custom Validation: Override the validate() method in your domain object:

    class User {
        public function validate(array $data) {
            // Custom logic
            return validator($data, $this->customRules())->validate();
        }
    }
    
  2. Event Hooks: Bind to yin.hydrated event for post-processing:

    Yin::hydrated(function ($object, $data) {
        // Example: Auto-generate UUIDs
        if ($object instanceof User) {
            $object->uuid = Str::uuid();
        }
    });
    
  3. Response Transformation: Use the toArray() method with custom logic:

    $hydrator->hydrate(User::class, $data)->toArray(function ($object) {
        return [
            'id' => $object->id,
            'email' => $object->email,
            // Custom fields
        ];
    });
    
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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
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