Weave 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

Enum Serializer Bundle Laravel Package

mrgoodbytes8667/enum-serializer-bundle

A Symfony bundle that adds serialization support for PHP enums, making it easy to convert backed enum cases to and from scalar values across APIs, Doctrine and config, with lightweight integration and minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. composer require mrgoodbytes8667/enum-serializer-bundle — this pulls in spatie/enum and symfony/serializer transitively.
  2. On Symfony, register the bundle in config/bundles.php:
    MrGoodbytes8667\EnumSerializerBundle\EnumSerializerBundle::class => ['all' => true],
    
    On Laravel there is no bundle registry — skip this step entirely and read the next point.
  3. Laravel reality check: this is a Symfony bundle, so the *Bundle::class plumbing (DI tags, services.yaml, Extension/Configuration) is dead weight in a Laravel app. What you actually want is the normalizer class it ships. Grab it and wire it by hand:
    // composer require symfony/serializer
    $serializer = new \Symfony\Component\Serializer\Serializer([
        new \MrGoodbytes8667\EnumSerializerBundle\Normalizer\EnumNormalizer(),
        new \Symfony\Component\Serializer\Normalizer\ObjectNormalizer(),
    ]);
    
    (Confirm the exact namespace by running composer show -a mrgoodbytes8667/enum-serializer-bundle, then grep -r "class .*Normalizer" vendor/. The Extension class also lists the service ID if you installed the whole bundle.)
  4. First use case: turning a spatie/enum value object into a scalar in a JSON response, and back again when hydrating a request DTO. Before this package, json_encode($dtoWithEnum) gives you the whole object graph; after it, you get "status": "active".

Implementation Patterns

Bind a configured serializer in a service provider (do this once, resolve everywhere):

$this->app->singleton(SerializerInterface::class, function () {
    return new Serializer([
        new EnumNormalizer(),                       // must come first
        new ObjectNormalizer(null, null, null, new ReflectionExtractor()),
        new JsonEncoder(),
    ], [new JsonEncoder()]);
});

Response DTOs / API Resources. Hydrate form input into a plain DTO, let the normalizer flatten enums, then hand the array to JsonResource:

class OrderResource extends JsonResource
{
    public function toArray($request): array
    {
        return app(SerializerInterface::class)->normalize($this->resource, 'json');
    }
}

This keeps spatie/enum objects out of your Eloquent models entirely — models keep the raw column, DTOs carry the enum, the serializer bridges them.

Denormalization for webhooks / job payloads. Incoming JSON with string enum fields:

$payload = app(SerializerInterface::class)
    ->deserialize($request->getContent(), OrderPayload::class, 'json');

The normalizer maps "active" back to OrderStatus::ACTIVE() via spatie's ::make()/::from() semantics, so your DTO constructor stays type-safe.

Queue payloads. SerializesModels handles Eloquent, not value objects. If an enum lands in a job property, either normalize it before dispatch (->value) or add __serialize/__unserialize to your DTO. Don't rely on the bundle here — Laravel's queue uses PHP's native serializer, not Symfony's.

Form request validation. Pair the serializer with a rule that matches the enum's cases, so bad strings fail fast instead of throwing on denormalize:

'status' => ['required', Rule::in(array_column(OrderStatus::cases(), 'value'))],

(For native PHP 8.1 backed enums, Rule::enum(OrderStatus::class) is cleaner — see gotchas.)

Eloquent side of the bridge. Keep the cast dumb — a string cast — and let the serializer own the enum conversion:

protected $casts = ['status' => 'string'];

Gotchas and Tips

  • Bundle wiring is useless in Laravel. Do not try to translate config/bundles.php into a provider by guessing the extension alias. Read EnumSerializerBundle::getContainerExtension() / DependencyInjection/Configuration.php for the real config key if you genuinely need it, but the honest answer is you only want the normalizer class.
  • Normalizer ordering is load-bearing. ObjectNormalizer will happily reflect over a spatie/enum object and emit {name, value, ...} if it registers first. Put EnumNormalizer at the front of the array and verify with dump($serializer->normalize($status)).
  • spatie/enum ≠ native enums. This package targets Spatie\Enum\Enum (the pre-8.1-style class). If your codebase uses \BackedEnum (PHP 8.1+), the normalizer's supportsNormalization() will return false and you'll fall through to ObjectNormalizer — silently. Laravel 11's Rule::enum() and Eloquent enum casts ('status' => OrderStatus::class) make the whole package redundant for native enums. Migrate before adding this dependency.
  • Serialization drift between layers. Normalized JSON uses ->value; PHP serialize() on a spatie enum stores the class name and internal state. If a job payload is produced by one path and consumed by the other, you get __PHP_Incomplete_Class or a string where an object was expected. Pick one boundary per transport.
  • Debugging supportsNormalization returns false. Add a temporary dd(get_class($data)) inside the call, or enumerate $serializer->getSupportedTypes($format) (Symfony 6.3+) — the package's getSupportedTypes() is where the format/case matrix lives.
  • Extension points: if you need custom casing (ACTIVE vs active) or a nested wrapper, don't fork — decorate. Make a small class UppercaseEnumNormalizer implements NormalizerInterface, DenormalizerInterface, NormalizerAwareInterface and delegate to the packaged normalizer, registering yours first.
  • Low adoption = read the source. Zero stars, zero dependents, a NOASSERTION license, and a mid-2024 release. Vet the license before shipping to production, pin the version in composer.json, and treat the normalizer as ~50 lines you could inline yourself if the dependency ever becomes a liability.
  • Laravel-native alternatives worth benchmarking first: spatie/laravel-data ships enum transformers out of the box, and Eloquent + Rule::enum() covers the DB/validation surface without a serializer at all. Only adopt this package if you're already committed to symfony/serializer for DTO hydration.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource