Product Decisions This Supports
- API Standardization: Enables consistent object-to-array serialization across Laravel APIs, reducing payload inconsistencies and improving developer velocity. Aligns with REST/GraphQL standards by supporting nested object normalization (e.g.,
RecursiveReflectionNormalizer for relationships like User->Posts).
- Data Pipeline Efficiency: Justifies adoption for high-throughput systems (e.g., event sourcing, ETL) where manual hydration/dehydration of Doctrine/Eloquent objects is error-prone. Reduces boilerplate in services like caching (Redis), queues, or analytics.
- Legacy Modernization: Supports "build vs. buy" for teams migrating from custom serialization logic (e.g.,
json_encode($object, JSON_UNESCAPED_SLASHES)) to a maintainable, framework-agnostic solution.
- Roadmap for GraphQL: Accelerates implementation of GraphQL resolvers by providing a robust normalization layer for complex object graphs, reducing resolver boilerplate.
- Third-Party Integration: Facilitates seamless data exchange with non-Laravel services (e.g., microservices, legacy PHP apps) by standardizing object serialization formats.
When to Consider This Package
- Avoid if:
- Your app doesn’t use Symfony Serializer or Doctrine/Eloquent (e.g., pure Laravel with no ORM or custom serialization).
- You need advanced features like circular reference handling, custom metadata, or multi-format serialization (JSON/XML/YAML)—use Symfony’s full
Serializer instead.
- Laravel 8+ with Symfony 5.4+: Normalt’s last release (2018) lacks Symfony 5+ support. Verify compatibility or fork the package.
- Your use case is simple POPOs without nested structures or Doctrine—Laravel’s native
Arrayable or toArray() suffices.
- You prioritize active maintenance—consider alternatives like
spatie/laravel-arrayable or jms/serializer.
- Consider if:
- You’re heavily using Eloquent/Doctrine and need efficient, consistent normalization for APIs, caching, or storage.
- Your team lacks dedicated serialization expertise but needs to support complex object graphs (e.g., polymorphic relationships).
- You’re building a data-heavy pipeline (e.g., ETL, event sourcing) where object hydration/dehydration is critical.
- You want to reduce technical debt by replacing ad-hoc serialization logic with a standardized library.
How to Pitch It (Stakeholders)
For Executives:
*"Normalt is a lightweight, MIT-licensed tool that automates the tedious and error-prone task of converting PHP objects to arrays—and back—critical for APIs, caching, and data processing. By adopting this, we:
- Reduce dev time by eliminating manual serialization logic (e.g.,
toArray() methods).
- Improve data consistency across APIs, microservices, and third-party integrations.
- Align with Symfony’s ecosystem, which Laravel already uses, minimizing new dependencies.
The package is stable (last tested with Symfony 4) and integrates seamlessly with Eloquent, making it a low-risk, high-reward choice for modernizing our data layer. While not actively maintained, its core functionality is battle-tested and can be forked if needed."*
For Engineering (Technical Lead):
*"This gives us three key advantages:
- Eloquent Integration: The
DoctrineNormalizer replaces manual toArray() methods for models, reducing boilerplate and improving consistency. Example:
// Before:
$user->toArray(); // Manual implementation
// After:
$normalizer->normalize($user); // Automatic, consistent
- Nested Object Support: The
RecursiveReflectionNormalizer handles complex relationships (e.g., User->Posts->Comments) without custom logic, which is critical for GraphQL or deeply nested APIs.
- Symfony Compatibility: Works with Laravel’s existing
symfony/serializer package, so no new dependencies beyond bernard/normalt.
Tradeoffs:
- Stale Maintenance: Last release was 2018. We’d need to test Symfony 5+ compatibility or fork the package. Recommend starting with a pilot (e.g., API responses) before full adoption.
- Limited Features: No built-in support for circular references or custom metadata, but we can combine it with Symfony’s
ObjectNormalizer if needed.
- Learning Curve: Developers will need to understand normalization concepts (e.g., delegators, normalizers), but the API is straightforward once familiarized."*
For Developers:
*"Replace this:
public function toArray()
{
return [
'id' => $this->id,
'name' => $this->name,
'posts' => $this->posts->map->toArray(), // Recursive!
];
}
With this:
$normalizer = new DoctrineNormalizer($entityManager);
$array = $normalizer->normalize($user); // Handles nested objects automatically.
No more manual loops, no more forgetting a field—just clean, consistent normalization. It even works for denormalization (array → object), which is useful for forms or API requests. Docs are clear, and the MIT license means no vendor lock-in. Start with the DoctrineNormalizer for Eloquent models, and the RecursiveReflectionNormalizer for complex object graphs."*