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

Normalt Laravel Package

bernard/normalt

Extra normalizers for Symfony’s Serializer plus an AggregateNormalizer delegator that selects the first supporting normalizer/denormalizer. Focuses on object-to-array normalization and array-to-object denormalization, with options like Doctrine and reflection-based normalizers.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Symfony Serializer Alignment: Normalt is a drop-in extension for Symfony’s Serializer, which Laravel already leverages via symfony/serializer (bundled since Laravel 5.5). This ensures minimal architectural disruption, as Normalt operates within the existing serialization stack.
  • Normalization-Centric Design: Focuses solely on object-to-array/array-to-object transformations, avoiding bloat from full-fledged serializers (e.g., JSON/XML). This aligns with Laravel’s API-first use cases (e.g., JsonResource, GraphQL resolvers) where normalization is a bottleneck.
  • Doctrine/Eloquent Synergy: The DoctrineNormalizer bridges Laravel’s Eloquent ORM with Symfony’s normalization pipeline, enabling seamless entity hydration/dehydration. Critical for:
    • API responses (e.g., replacing manual toArray() in JsonResource).
    • Caching layers (e.g., Redis with serialized Eloquent models).
    • Data pipelines (e.g., ETL jobs converting database records to arrays).
  • Extensibility: The AggregateNormalizer allows mixing Normalt’s normalizers with Symfony’s (e.g., GetSetMethodNormalizer) or custom ones, future-proofing the integration.

Integration Feasibility

  • Laravel Compatibility:
    • Symfony Version Gap: Normalt’s last release (2018) targets Symfony 2.3–4.0, while Laravel 8+ uses Symfony 5.4+. Risk: Potential BC breaks (e.g., NormalizerInterface changes).
      • Mitigation: Use a composer patch or fork to backport Symfony 5 support (focus on NormalizerInterface and DenormalizerInterface).
    • Service Container: Normalt lacks Laravel service provider bindings. Solution: Register normalizers manually in AppServiceProvider:
      $this->app->bind(NormalizerInterface::class, function ($app) {
          return new AggregateNormalizer([
              new DoctrineNormalizer($app->make(EntityManager::class)),
              new GetSetMethodNormalizer(),
          ]);
      });
      
    • Eloquent Integration: No native Eloquent support, but DoctrineNormalizer works with Doctrine’s EntityManager. Workaround: Use Doctrine’s EntityManager for Eloquent models (via doctrine/dbal or illuminate/database).
  • Dependency Conflicts:
    • Doctrine/Common: Required for DoctrineNormalizer. Laravel’s illuminate/database already includes Doctrine classes, so no additional dependencies.
    • PHP 8.0+: Normalt’s reflection-based normalizers may need updates for PHP 8’s constructor property promotion or named arguments.

Technical Risk

  • Stagnation Risk:
    • No Maintenance: Last release in 2018; no issues/PRs since 2019. Impact:
      • Unpatched Symfony 5+ BC breaks.
      • No PHP 8.x compatibility (e.g., constructor changes).
    • Mitigation: Treat as a one-time integration with a forked repo for critical fixes.
  • Performance:
    • RecursiveReflectionNormalizer uses reflection, which can be slow for deep object graphs (e.g., User->Posts->Comments). Benchmark against:
      • Laravel’s native Arrayable trait.
      • Symfony’s ObjectNormalizer (with caching enabled).
  • Edge Cases:
    • Circular References: Normalt lacks built-in handling (unlike Symfony’s ObjectNormalizer). Solution: Combine with Symfony’s ObjectNormalizer or implement a custom CircularReferenceHandler.
    • Denormalization Failures: If the input array lacks required keys, Normalt may throw exceptions. Solution: Add validation layers (e.g., Symfony’s Validator).
  • Testing:
    • Minimal test coverage (PhpSpec). Risk: Undiscovered bugs in nested object graphs or Doctrine edge cases (e.g., inheritance, proxies).

Key Questions

  1. Symfony 5+ Compatibility:
    • Can Normalt’s NormalizerInterface be made compatible with Symfony 5.4+? If not, is a fork/patch feasible?
  2. Performance Tradeoffs:
    • How does Normalt’s performance compare to Laravel’s Arrayable or Symfony’s ObjectNormalizer for our object graphs?
  3. Doctrine vs. Eloquent:
    • Will DoctrineNormalizer work with Eloquent models, or do we need to use Doctrine’s EntityManager directly?
  4. Denormalization Safety:
    • How will we handle malformed input arrays during denormalization (e.g., missing fields, invalid types)?
  5. Maintenance Plan:
    • If Normalt is forked, who will own the Laravel-specific updates (e.g., PHP 8.1+, Symfony 6+)?
  6. Feature Gaps:
    • Do we need circular reference handling, custom metadata, or contextual normalization? If so, how will we extend Normalt?

Integration Approach

Stack Fit

  • Laravel-Specific Synergies:
    • API Resources: Replace manual toArray() in JsonResource with Normalt’s DoctrineNormalizer for Eloquent models:
      public function toArray($request)
      {
          return resolve(NormalizerInterface::class)->normalize($this->resource);
      }
      
    • GraphQL: Use Normalt for resolver payloads (e.g., normalize User objects to arrays for GraphQL responses).
    • Caching: Serialize Eloquent models to arrays for Redis/Memcached storage:
      $normalizer = app(NormalizerInterface::class);
      $cachedData = $normalizer->normalize($model);
      cache()->put("model:$id", $cachedData, now()->addHour());
      
    • Testing: Normalize models for consistent test data (e.g., API response assertions).
  • Symfony Integration Points:
    • Serializer Component: Normalt integrates with Laravel’s symfony/serializer bundle, enabling reuse of existing encoder/decoder configurations.
    • Validator: Combine with Symfony’s Validator for denormalization safety (e.g., validate arrays before denormalizing).
  • Alternatives Rejected:
    • Spatie Arrayable: Lacks denormalization and Doctrine support.
    • JMS Serializer: Overkill for Laravel’s needs; heavier and less idiomatic.
    • Native Arrayable: Limited to normalization; no denormalization or ORM integration.

Migration Path

  1. Phase 1: Assessment (1–2 weeks)
    • Audit existing normalization logic (e.g., toArray() methods, custom serializers).
    • Identify high-impact use cases (e.g., API resources, caching, ETL).
    • Benchmark Normalt against current solutions (e.g., manual toArray(), Arrayable).
  2. Phase 2: Pilot Integration (2–3 weeks)
    • Step 1: Add Normalt to composer.json (with Symfony 5 patch if needed).
    • Step 2: Register normalizers in AppServiceProvider:
      $this->app->bind(NormalizerInterface::class, function ($app) {
          return new AggregateNormalizer([
              new DoctrineNormalizer($app->make(EntityManager::class)),
              new GetSetMethodNormalizer(),
              // Add custom normalizers if needed
          ]);
      });
      
    • Step 3: Replace toArray() in a non-critical JsonResource with Normalt’s normalizer.
    • Step 4: Test denormalization for a simple Eloquent model.
  3. Phase 3: Full Rollout (3–4 weeks)
    • Step 1: Gradually replace toArray() methods across API resources.
    • Step 2: Integrate with caching layer (e.g., serialize models to arrays for Redis).
    • Step 3: Extend to GraphQL resolvers or data pipelines.
    • Step 4: Add custom normalizers for domain-specific objects (e.g., DTOs).
  4. Phase 4: Optimization (Ongoing)
    • Benchmark performance and adjust normalizer order (e.g., prioritize DoctrineNormalizer for entities).
    • Implement fallback mechanisms for unsupported types (e.g., log warnings for circular references).

Compatibility

  • Symfony 5+:
    • Patch Required: Update NormalizerInterface and DenormalizerInterface implementations to match Symfony 5.4+.
    • Test: Verify with Symfony’s Serializer component (e.g., symfony/serializer:^5.4).
  • PHP 8.0+:
    • Constructor Changes: Update RecursiveReflectionNormalizer to handle PHP 8’s constructor property promotion.
    • Named Arguments: Ensure normalizers support named arguments in methods.
  • Doctrine/Eloquent:
    • DoctrineNormalizer: Works with Doctrine’s EntityManager. For Eloquent, use Doctrine’s EntityManager via doctrine/dbal or wrap Eloquent models in Doctrine entities temporarily.
    • **
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
codifyo/ts-generator-bundle
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor