Add new serializer empty_data feature doc#8914
Merged
javiereguiluz merged 3 commits intosymfony:4.1from Jun 27, 2018
Merged
Conversation
c4d61f9 to
2ba3fdd
Compare
fabpot
requested changes
Jan 19, 2018
components/serializer.rst
Outdated
| ---------------------- | ||
|
|
||
| Value Objets are difficult to handle because they often require parameters in the constructor. If the input omit one | ||
| of theses parameters the serializer will throw an exeception because it can't create the object. |
symfony-splitter
pushed a commit
to symfony/serializer
that referenced
this pull request
Jan 19, 2018
…ption for denormalization (Nek-) This PR was squashed before being merged into the 4.1-dev branch (closes #25493). Discussion ---------- [Serializer] `default_constructor_arguments` context option for denormalization | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | (there is no RFC for this) | License | MIT | Doc PR | symfony/symfony-docs#8914 ## Problems In the case you want to deserialize value-objects, if all the data required by its constructor are **not** given as input, the serializer will throw a simple `RuntimeException` exception. This makes impossible to catch it. (as current fix on my projects I use exception message to be sure to catch the good one X.x") The second problem is a missing feature to fill the required object with an empty one. This needs to be defined by the user because the serializer can't guess how to build it. Here is a project that exposes the problem of the current behavior. https://github.com/Nek-/api-platform-value-object ## Solutions suggested I suggest a solution in 2 parts because the second part is more touchy. 1. Replace the current exception by a new specific one 2. Add a new `empty_data` option to the context of deserialization so you can specify data for objects impossible to instantiate, this is great because the serializer no more throw exception and the validator can then work as expected and send violations to the user. This solution is inspired by forms solutions to fix the issue with value objects Here is what you can do with this feature: ```php class DummyValueObject { public function __construct($foo, $bar) { $this->foo = $foo; $this->bar = $bar; } } $empty = new DummyValueObject('', ''); $result = $normalizer->denormalize(['foo' => 'Hello'], DummyValueObject::class, 'json', [ 'empty_data' => [ DummyValueObject::class => $empty, ], ]); // It's impossible to construct a DummyValueObject with only "foo" value. So the serializer // will replace it with the given empty data ``` There are 2 commits so I can quickly provide you only the first point if you want. Hope you'll like this. ## Solution after discussion 1. New exception `MissingConstructorArgumentsException` 2. New context option `default_constructor_arguments` ```php class DummyValueObject { public function __construct($foo, $bar) { $this->foo = $foo; $this->bar = $bar; } } $result = $normalizer->denormalize(['foo' => 'Hello'], DummyValueObject::class, 'json', [ 'default_constructor_arguments' => [ DummyValueObject::class => ['foo' => '', 'bar' => ''], ], ]); // DummyValueObject is contructed with the given `foo` and empty `bar` ``` Commits ------- 1523a85 [Serializer] context option for denormalization
fabpot
added a commit
to symfony/symfony
that referenced
this pull request
Jan 19, 2018
…ption for denormalization (Nek-) This PR was squashed before being merged into the 4.1-dev branch (closes #25493). Discussion ---------- [Serializer] `default_constructor_arguments` context option for denormalization | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | (there is no RFC for this) | License | MIT | Doc PR | symfony/symfony-docs#8914 ## Problems In the case you want to deserialize value-objects, if all the data required by its constructor are **not** given as input, the serializer will throw a simple `RuntimeException` exception. This makes impossible to catch it. (as current fix on my projects I use exception message to be sure to catch the good one X.x") The second problem is a missing feature to fill the required object with an empty one. This needs to be defined by the user because the serializer can't guess how to build it. Here is a project that exposes the problem of the current behavior. https://github.com/Nek-/api-platform-value-object ## Solutions suggested I suggest a solution in 2 parts because the second part is more touchy. 1. Replace the current exception by a new specific one 2. Add a new `empty_data` option to the context of deserialization so you can specify data for objects impossible to instantiate, this is great because the serializer no more throw exception and the validator can then work as expected and send violations to the user. This solution is inspired by forms solutions to fix the issue with value objects Here is what you can do with this feature: ```php class DummyValueObject { public function __construct($foo, $bar) { $this->foo = $foo; $this->bar = $bar; } } $empty = new DummyValueObject('', ''); $result = $normalizer->denormalize(['foo' => 'Hello'], DummyValueObject::class, 'json', [ 'empty_data' => [ DummyValueObject::class => $empty, ], ]); // It's impossible to construct a DummyValueObject with only "foo" value. So the serializer // will replace it with the given empty data ``` There are 2 commits so I can quickly provide you only the first point if you want. Hope you'll like this. ## Solution after discussion 1. New exception `MissingConstructorArgumentsException` 2. New context option `default_constructor_arguments` ```php class DummyValueObject { public function __construct($foo, $bar) { $this->foo = $foo; $this->bar = $bar; } } $result = $normalizer->denormalize(['foo' => 'Hello'], DummyValueObject::class, 'json', [ 'default_constructor_arguments' => [ DummyValueObject::class => ['foo' => '', 'bar' => ''], ], ]); // DummyValueObject is contructed with the given `foo` and empty `bar` ``` Commits ------- 1523a85 [Serializer] context option for denormalization
2ba3fdd to
844154e
Compare
Contributor
Author
|
@fabpot fixed |
javiereguiluz
approved these changes
Feb 20, 2018
Member
javiereguiluz
left a comment
There was a problem hiding this comment.
@Nek- thanks for contributing this doc. I liked it a lot and everything is well explained. I just made a minor reword to focus more on the general use case ("Handling Constructor Arguments") instead of the "value object" detail. Thanks!
dunglas
reviewed
May 16, 2018
| Handling Constructor Arguments | ||
| ------------------------------ | ||
|
|
||
| If the constructor of a class defines arguments, as usually happens with |
Member
There was a problem hiding this comment.
It's not exact: the serializer deals well with constructor arguments, if they are present in the data to deserialize.
The default_constructor_arguments is useful only when the value has not been provided in the data to deserialize.
Contributor
Author
|
Fixed and rebased. 👍 |
Member
|
@Nek- I'm sorry it took us so long to merge. Thanks! |
javiereguiluz
added a commit
that referenced
this pull request
Jun 27, 2018
…uiluz) This PR was merged into the 4.1 branch. Discussion ---------- Add new serializer empty_data feature doc This is the documentation related to the following feature: symfony/symfony#25493 Commits ------- 9f31bbb Fix not precise enough sentence b0d3fe8 Minor reword 5a48201 Add new serializer empty_data feature doc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is the documentation related to the following feature: symfony/symfony#25493