gbprod/uuid-normalizer
A Symfony Serializer normalizer for Ramsey UUIDs. Install via Composer, register UuidNormalizer and UuidDenormalizer as serializer.normalizer services, and serialize or deserialize UUIDs without "Not a time-based UUID" errors. Requires PHP 7.4+.
Architecture fit
UuidNormalizer, UuidDenormalizer) implementing symfony/serializer's NormalizerInterface / DenormalizerInterface, mapping Ramsey\Uuid\UuidInterface ↔ canonical string. No service provider, no config, no facade, no Laravel package discovery, no Artisan surface.symfony/serializer? Vanilla Laravel (Eloquent toArray, JsonResource, FormRequest, Cast) does not — so baseline value for a stock Laravel app is approximately zero, and adopting this package implicitly means adopting symfony/serializer to solve a UUID problem.symfony/serializer is already in the stack (API Platform, a hexagonal ports-and-adapters boundary layer, CQRS/queue payloads, laravel-data with its serializer bridge), it closes a real and well-documented gap: ObjectNormalizer cannot handle Ramsey UUIDs and throws the "Not a time-based UUID / UnsupportedOperationException" class of errors the README cites.UidNormalizer for symfony/uid. This package is only relevant when Ramsey is the UUID of record — which it is in Laravel, since Str::uuid() returns a Ramsey\Uuid\UuidInterface. Confirm no dual UUID library situation.Integration feasibility
composer require, then compose the normalizer chain explicitly (or tag serializer.normalizer if a bridge container is in use). Realistically half a day plus tests.Technical risk
ramsey/uuid v5 and symfony/serializer v8 compatibility is unproven. Pin and test.Key questions
symfony/serializer sit in our request, response, and queue paths today? If the answer is "nowhere," this package is a non-starter.char(36) or binary(16) in persistence, and which representation is intended to cross the wire?Stack fit
ramsey/uuid ^4, symfony/serializer ^6/^7. Nothing Laravel-specific is provided — registration is entirely our code.SerializerServiceProvider (or App\Support\SerializerFactory) that composes the chain explicitly — normalizers [UuidNormalizer, DateTimeNormalizer, ObjectNormalizer], denormalizers [UuidDenormalizer, …]. Normalizer ordering is the entire integration; get it wrong and the original exception returns intermittently.laravel-data is the DTO layer, do not add this at all — use a custom DataTransformer/cast. That is the idiomatic path and avoids a second serialization stack in the same request.Migration path
UuidInterface property, round-trip both directions, assert exact string format, assert 422 on malformed input.symfony/serializer where none existed, stop. The cost of that adoption dwarfs the benefit; a 40-line Laravel cast or transformer solves the same problem with none of the dependency surface.->toString() / Uuid::fromString() mappers at the boundary, consolidate.App\Serialization under our namespace. Removes the dependency and the license question at effectively zero maintenance cost.Compatibility
UuidInterface only — no symfony/uid, no generic string identifiers, no composite keys.not assume) supports*() precedence against Symfony's UidNormalizer.Sequencing
Maintenance
ramsey/uuid or symfony/serializer major.Support
Scaling
Failure modes
ObjectNormalizer (or UidNormalizer) claims UuidInterface first; symptom is the original "Not a time-based UUID" error resurfacing after an unrelated composer update.binary(16) column emitted as canonical string, or the reverse — produces valid-looking but wrong identifiers that propagate downstream and are hard to detect after the fact.skip_null_values), not by this package; test explicitly rather than reasoning about it.ramsey/uuid v5 or symfony/serializer v8 returns to a hard failure with no upstream fix timeline.Ramp-up
How can I help you explore Laravel packages today?