Skip to content

Commit

Permalink
feat: register DateTimeNormalizer by default (#119)
Browse files Browse the repository at this point in the history
* Add a note about DateTimeNormalizer in README

Without it, serializing DateTimeInterface instances leads to huge serialized data.

* Register the DateTimeNormalizer in the Symfony bundle

* minor tweaks

---------

Co-authored-by: Kévin Dunglas <[email protected]>
  • Loading branch information
mlocati and dunglas authored Feb 23, 2023
1 parent c73ccf7 commit d729dc3
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 14 deletions.
19 changes: 11 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,14 @@ use Dunglas\DoctrineJsonOdm\Serializer;
use Dunglas\DoctrineJsonOdm\Type\JsonDocumentType;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
use Symfony\Component\Serializer\Normalizer\BackedEnumNormalizer;
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;

if (!Type::hasType('json_document')) {
Type::addType('json_document', JsonDocumentType::class);
Type::getType('json_document')->setSerializer(
new Serializer([new ArrayDenormalizer(), new ObjectNormalizer()], [new JsonEncoder()])
new Serializer([new BackedEnumNormalizer(), new DateTimeNormalizer(), new ArrayDenormalizer(), new ObjectNormalizer()], [new JsonEncoder()])
);
}

Expand Down Expand Up @@ -214,7 +216,6 @@ For using the built-in type mapper:
);
```


### Limitations when updating nested properties

Due to how Doctrine works, it will not detect changes to nested objects or properties.
Expand Down Expand Up @@ -291,21 +292,23 @@ class Kernel extends BaseKernel

**How can I add additional normalizers?**

The Symfony Serializer is easily extensible. This bundle registers and uses a service with ID `dunglas_doctrine_json_odm.serializer` as the serializer for the JSON type. This means we can easily override it in our `services.yaml` to use additional normalizers.
As an example we use the Symfony `DateTimeNormalizer` service, so we do have support for any property that is an instance of `\DateTimeInterface`. Be aware that the order of the normalizers might be relevant depending on the normalizers you use.
The Symfony Serializer is easily extensible. This bundle registers and uses a service with ID `dunglas_doctrine_json_odm.serializer` as the serializer for the JSON type.
This means we can easily override it in our `services.yaml` to use additional normalizers.
As an example we inject a custom normalizer service. Be aware that the order of the normalizers might be relevant depending on the normalizers you use.

```yaml
# Add DateTime Normalizer to Dunglas' Doctrine JSON ODM Bundle
dunglas_doctrine_json_odm.serializer:
class: Dunglas\DoctrineJsonOdm\Serializer
arguments:
- ['@dunglas_doctrine_json_odm.normalizer.array', '@serializer.normalizer.datetime', '@dunglas_doctrine_json_odm.normalizer.object']
- ['@App\MyCustom\Normalizer', '@?dunglas_doctrine_json_odm.normalizer.backed_enum', '@dunglas_doctrine_json_odm.normalizer.datetime', '@dunglas_doctrine_json_odm.normalizer.array', '@dunglas_doctrine_json_odm.normalizer.object']
- ['@serializer.encoder.json']
- '@?dunglas_doctrine_json_odm.type_mapper'
public: true
autowire: false
autoconfigure: false
```

As a side note: If you happen to use [Autowiring](https://symfony.com/doc/current/service_container/autowiring.html) in your `services.yaml` you might need to set `autowire: false` too. Same goes for `autoconfigure: false` in case you're using [Autoconfiguration](https://symfony.com/doc/current/service_container.html#the-autoconfigure-option).

**When the namespace of a used entity changes**

For classes without [type aliases](#using-type-aliases), because we store the `#type` along with the data in the database, you have to migrate the already existing data in your database to reflect the new namespace.
Expand All @@ -321,7 +324,7 @@ WHERE 'AppBundle\\\Entity\\\Bar' = JSON_EXTRACT(misc, '$."#type"');

## Credits

This bundle is brought to you by [Kévin Dunglas](https://dunglas.fr) and [awesome contributors](https://github.com/dunglas/doctrine-json-odm/graphs/contributors).
This bundle is brought to you by [Kévin Dunglas](https://dunglas.dev) and [awesome contributors](https://github.com/dunglas/doctrine-json-odm/graphs/contributors).
Sponsored by [Les-Tilleuls.coop](https://les-tilleuls.coop).

## Former Maintainers
Expand Down
16 changes: 10 additions & 6 deletions src/Bundle/Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

<services>

<service id="dunglas_doctrine_json_odm.normalizer.backed_enum" class="Symfony\Component\Serializer\Normalizer\BackedEnumNormalizer" public="false" />

<service id="dunglas_doctrine_json_odm.normalizer.datetime" class="Symfony\Component\Serializer\Normalizer\DateTimeNormalizer" public="false" />

<service id="dunglas_doctrine_json_odm.normalizer.array" class="Symfony\Component\Serializer\Normalizer\ArrayDenormalizer" public="false" />

<service id="dunglas_doctrine_json_odm.type_mapper" class="Dunglas\DoctrineJsonOdm\TypeMapper" public="false" />

<service id="dunglas_doctrine_json_odm.normalizer.object" class="Symfony\Component\Serializer\Normalizer\ObjectNormalizer" public="false">
<argument type="service" id="serializer.mapping.class_metadata_factory" on-invalid="ignore" />
<argument>null</argument><!-- name converter -->
Expand All @@ -13,15 +22,10 @@
<argument type="service" id="serializer.mapping.class_discriminator_resolver" on-invalid="ignore" />
</service>

<service id="dunglas_doctrine_json_odm.normalizer.array" class="Symfony\Component\Serializer\Normalizer\ArrayDenormalizer" public="false" />

<service id="dunglas_doctrine_json_odm.normalizer.backed_enum" class="Symfony\Component\Serializer\Normalizer\BackedEnumNormalizer" public="false" />

<service id="dunglas_doctrine_json_odm.type_mapper" class="Dunglas\DoctrineJsonOdm\TypeMapper" public="false" />

<service id="dunglas_doctrine_json_odm.serializer" class="Dunglas\DoctrineJsonOdm\Serializer" public="true">
<argument type="collection">
<argument type="service" id="dunglas_doctrine_json_odm.normalizer.backed_enum" on-invalid="ignore" />
<argument type="service" id="dunglas_doctrine_json_odm.normalizer.datetime" />
<argument type="service" id="dunglas_doctrine_json_odm.normalizer.array" />
<argument type="service" id="dunglas_doctrine_json_odm.normalizer.object" />
</argument>
Expand Down
1 change: 1 addition & 0 deletions tests/Fixtures/AppKernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ protected function configureContainer(ContainerBuilder $container, LoaderInterfa
$container->loadFromExtension('framework', [
'secret' => 'jsonodm',
'test' => null,
'http_method_override' => false,
]);

$container->loadFromExtension('doctrine', [
Expand Down

0 comments on commit d729dc3

Please sign in to comment.