tsantos / fast-object-normalizer
Generate dedicated normalizers for your objects to increase serialization performance
Requires
- php: >8.1
- phpdocumentor/reflection-docblock: ^5.3
- symfony/property-info: ^6.1
- symfony/serializer: ^6.1
- twig/twig: ^3.4
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.10
- phpbench/phpbench: ^1.2
- phpunit/phpunit: ^9.5
- symfony/cache: ^6.1
- symfony/property-access: ^6.1
This package is auto-updated.
Last update: 2024-11-29 06:36:04 UTC
README
Symfony Object Normalizer that improves the serialization process up to 5x (e.g. 400%) compared to built-in normalizers. This boost of performance can be accomplished because this normalizer generates dedicated normalizes to your data classes, so you don't need to worry about runtime overhead like reflections or code relying on metadata (e.g. ClassMetadata).
Instalation
composer require tsantos/fast-object-normalizer
Symfony Applications
This package ships with a Symfony Bundle that autmatically adds the normalizer to the normalizer stack.
Applications using Flex
Just install the package and the Symfony Flex automatically register the bundle into your application.
Applications not using Flex
You need to register the bundle manually:
<?php // config/bundles.php return [ // .. TSantos\FastObjectNormalizer\Bridge\Symfony\FastObjectNormalizerBundle::class => ['all' => true] ];
Standalone Applications
For applications using Symfony Serializer as a standalone component, you'll need to register the normalizer manually:
<?php require 'vendor/autoload.php'; use Symfony\Component\Serializer\Mapping\ClassDiscriminatorFromClassMetadata; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory; use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer; use Symfony\Component\Serializer\Normalizer\ObjectDenormalizer; $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); $discriminator = new ClassDiscriminatorFromClassMetadata($classMetadataFactory); $serializer = new Serializer([ new ArrayDenormalizer(), new FastObjectNormalizer( classGenerator: new NormalizerClassGenerator($classMetadataFactory, $discriminator), classDumper: new NormalizerClassDumper('./var/cache/serializer'), classMetadataFactory: $classMetadataFactory, ), new ObjectNormalizer($classMetadataFactory) ], ['json' => new JsonEncoder()]);
Note that ObjectNormalizer
still in the normalizer stack. This is not a requirement, but it is a good idea to have
the built-in normalizer working because Fast Object Normalizer
may not support the object that is being serialized.
Configuration
Fast Object Normalizer
is aimed to serialize data class (e.g: DTO), but in somecases it is possible that your
application tries to serialize an object which holds a resource or a connection and normally there is an exclusive
normalizer that deals with that type. To ensure that Fast Object Normalizer
skip such types, you can configure it
to serialize only types that matchs some pattern:
<?php $normalizer = new FastObjectNormalizer( includedTypes: ['^App\\\Entity'] //... other args here )
# config/packages/fast_object_normalizer.yaml fast_object_normalizer: includedTypes: ["^App\\Entity"]
Configuring the normalizer with includedTypes
you know exactly what types the normalizer will support. In the major of
times, you'll opt to this configuration to avoid weird behaviors.
There is also the oposite of includedTypes
which now will accepts all types except those defined in the excludedList
:
<?php $normalizer = new FastObjectNormalizer( includedTypes: ['^App\\\Entity'] //... other args here )
# config/packages/fast_object_normalizer.yaml fast_object_normalizer: excludedTypes: ["^Some\\Vendor\\Object"]
Finally, you can combine both options:
<?php $normalizer = new FastObjectNormalizer( includedTypes: ['^App\\\Entity'], excludedTypes: ['^App\\\Entity\\\\ExcludedType'], //... other args here )
# config/packages/fast_object_normalizer.yaml fast_object_normalizer: excludedTypes: ['^App\\\Entity'] includedTypes: ["^App\\\Entity\\\\ExcludedType"]
With this configuration, you are allowing all types starting with App\Entity
but excluding App\Entity\ExcludedType
.
YOU MUST BE AWARE
This packages tries to be the more transparent as possible to allow you to use it without break your application.
As explained previously, this package creates dedicated normalizers to serialize your data as fast as possible, which
means that the built-in normalizer AbstractObjectNormalizer
will not be reached. It means that features like attribute
grouping, null value skipping, attribute callback etc. had to be reimplemented here to boost performance, that is,
it is possible to have some different behaviors compared to AbstractObjectNormalizer
. Please, open an issue if you
find some divergent behavior.
The table below list all the features currently supported by built-in normalizer and Fast Object Normalizer
.
If you want to use Fast Object Normalizer
but need a specific feature to be implemented, I'd be very happy to
point you in how we can implement it.