-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Serializer][PropertyInfo][PropertyAccess] Refactoring plan for AbstractObjectNormalizer and related code #30818
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
…terface (dmaicher) This PR was merged into the 4.3-dev branch. Discussion ---------- [Serializer] provide new ObjectPropertyListExtractorInterface | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | related to symfony/symfony#30818 | License | MIT | Doc PR | - EUFOSSA Hackathon As discussed with @joelwurtz this adds a new `ObjectPropertyListExtractorInterface` and a default implementation. See symfony/symfony#30818 > A new interface will be provided ObjectPropertyListExtractorInterface (name can change), that allow getting attributes based on an object. A default implementation will be provided that use the PropertyListExtractorInterface and a class resolver, as the latter one only rely on class name, it may be important to have this distinction (this will allow features that rely on a specific value of the object to get the current property list, like exclusion policy) Commits ------- 997270f7ac [Serializer] provide new ObjectPropertyListExtractorInterface
…terface (dmaicher) This PR was merged into the 4.3-dev branch. Discussion ---------- [Serializer] provide new ObjectPropertyListExtractorInterface | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | related to #30818 | License | MIT | Doc PR | - EUFOSSA Hackathon As discussed with @joelwurtz this adds a new `ObjectPropertyListExtractorInterface` and a default implementation. See #30818 > A new interface will be provided ObjectPropertyListExtractorInterface (name can change), that allow getting attributes based on an object. A default implementation will be provided that use the PropertyListExtractorInterface and a class resolver, as the latter one only rely on class name, it may be important to have this distinction (this will allow features that rely on a specific value of the object to get the current property list, like exclusion policy) Commits ------- 997270f [Serializer] provide new ObjectPropertyListExtractorInterface
…lwurtz) This PR was merged into the 4.3-dev branch. Discussion ---------- [Serializer] Experimental for ObjectListExtractor | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #30904 | License | MIT | Doc PR | - Related to #30818 I want to mark this class as `@expiremental` until we have the full refactoring done of the Serializer, also this would allow change needed if some behavior was not correctly taken into care in 4.3 Mark also `final` for the default implementation as we don't want that to be extendable and user should use composition over inheritance. Commits ------- b0cdf45 Set object list extractor as expiremental, and use final for default implementation
This PR was squashed before being merged into the 4.3-dev branch (closes #30888). Discussion ---------- [serializer] extract normalizer tests to traits eufossa | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | Relates to #30818 | License | MIT | Doc PR | - As discussed with @joelwurtz, extract normalizer functionality tests into traits to ensure consistent behaviour of all normalizers. * [x] Rebase when #30977, #30950 and #30907 are merged to master **blocker** * [x] Clean up order of trait inclusion and methods in the tests * [x] Clean up fixture classes of the traits. I started having one class named the same as the trait, where possible Stuff that we should do eventually, but can also do in separate pull requests, after this one has been merged: * [ ] Extract all features that we can (the existing normalizer tests should more or less only have the legacy tests in them, all functionality should be in trait) * [ ] Run test coverage and increase coverage so that we cover all important features and all relevant error cases. Commits ------- 2b6ebea [serializer] extract normalizer tests to traits
@joelwurtz How can we move forward with this issue and the related PRs? Best could be to dedicate some time (online?) with involved people (to be defined) to try to reach a point where we can actually merge something? I would be more than happy to help and organize such a "mini-hackaton". /cc @dunglas |
I would be glad to attend to such hackathon too. |
@joelwurtz Friendly ping, do you think you could dedicate some time to organize a meetup to help move forward the various changes you proposed? |
Thanks for the ping, didn't see the first one (lost in notifications during holidays ^^). Such a mini hackaton would definitely help with @Korbeil also as he tries to take most of the work. I am mostly available during classic work time (should be the same for @Korbeil), |
Thank you for this issue. |
No @carsonbot, it's still on the roadmap. |
This PR was merged into the 6.1 branch. Discussion ---------- [Serializer] Add context builders | Q | A | ------------- | --- | Branch? | 6.1 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | Fixes partially #30818 | License | MIT | Doc PR | TODO This PR introduces ContextBuilders as discussed in #30818. The main idea here is to introduce an abstract context builder that could be extended to create concrete context builders. These context builders will allow serialization context construction using withers (maybe setters are better?) while providing validation, documentation, and IDE autocompletion. Once construction is ready, `toArray` (maybe `build` is better?) can be called to generate the actual serialization context. For example: ```php use Symfony\Component\Serializer\Context\Encoder\CsvEncoderContextBuilder; use Symfony\Component\Serializer\Context\Normalizer\DateTimeNormalizerContextBuilder; $initialContext = ['custom_key' => 'custom_value']); $contextBuilder = (new DateTimeNormalizerContextBuilder() ->withContext($initialContext) ->withFormat('Y_m_d') ->withTimezone('GMT'); $contextBuilder = (new CsvEncoderContextBuilder()) ->withContext($contextBuilder->toArray()) ->withDelimiter('-') ->withHeaders(['foo', 'bar']); $this->serializer->serialize($data, 'csv', $contextBuilder->toArray()); // Serialization context will be: // [ // 'custom_key' => 'custom_value', // 'datetime_format' => 'Y_m_d', // 'datetime_timezone' => DateTimeZone instance, // 'csv_delimiter' => '-', // 'csv_headers' => ['foo', 'bar'], // ] ``` Commits ------- f1b078c Add context builers
Hello,
AbstractObjectNormalizer
has a long list of ongoing issues and pull request, we got a talk at Paris Symfony Live with @dunglas @fbourigault and @soyuka on how we want to move forward, here is a resume of our talk and what we would like to achieve for the future:Current State and Context
At the origin this normalizer was done for API Platform and many other third party libraries / project, in order to have a normalizer that is able to normalize and denormalize any data object (specifically doctrine entities).
ObjectNormalizer
,PropertyNormalizer
andGetSetMethodNormalizer
were already existing, but were having slightly different beahvior, that's why two abstract class were createdAbstractNormalizer
andAbstractObjectNormalizer
Over time, lot of missing features in the ObjectNormalizer were added on both the AbstractObjectNormalizer and the AbstractNormalizer as we needed the same features there.
The main problem with the inheritance model is that it's very hard to customize some behavior without having to write a lot of code. For example, the current API Platform Normalizer has a lot of duplicated code as he extends the
AbstractObjectNormalizer
and must rewrite the logic around setting and getting value.If we look at the main differences between those 3 normalizers they just have a different way of setting and getting value for a given object:
Plan
Tests
creating a rock solid test suite that handles every features of those 3 normalizers implementing the
NormalizerInterface
. Thanks to this, the refactor can be handled without breaking the working behavior. Also this test suite would be used by other people that want to provide different ways of dealing with object normalization like:A generated normalizer (like it can be done with the Automapper proposal)
A bridge for the JMS serializer
...
See #30888
Feature set
Current normalizers already handle lot of features, but some of them, that are widely used in the
JMS/Serializer
library are missing. Goal is to provide some of this features or at least extension points.New Normalizer(s)
We strongly believe that those 3 normalizers can be merged into a single normalizer, each feature that they currently support should be provided by a call to another object:
Serializer should have an hard dependency on
symfony/property-access
component, a bridge interface may be provided to handle how value can be setted or gettted: also should allow a new extension point that will allow virtual propertyA new interface will be provided
ObjectPropertyListExtractorInterface
(name can change), that allow getting attributes based on an object. A default implementation will be provided that use thePropertyListExtractorInterface
and a class resolver, as the latter one only rely on class name, it may be important to have this distinction (this will allow features that rely on a specific value of the object to get the current property list, like exclusion policy)See #30904
PropertyListExtractorInterface
orObjectPropertyListExtractorInterface
See #30960
Groups
,Max Depth
,Attributes
,IgnoredAttributes
,Ignore
and many other features that influence the way an attribute is allowed or disallowed on a normalizer can be also delegated to the extraction mechanism by implementing thePropertyListExtractorInterface
orObjectPropertyListExtractorInterface
See #30980
InstantiatorInterface
), which will provide a new extension pointSee #30956
Name converter will certainly stay the same
Circular Reference could be delegated to a new Normalizer that decore another normalizer if possible (if not it will stay in this normalizer)
Discriminator Handling could be delegated to a new denormalizer that decore another denormalizer: as this is mainly to find the correct class when denormalizing
PropertyInfo
See #30704
PropertyAccess
See #30704
Context
All of those interface / extensions point will work with a
$context
variable. Like the http-client component, this$context
will be an array.$defaultContext
attribute in the constructor to handle global configuration.-See #38542
ContextBuilder
class that allow a API that play nicely with IDE and discovery for setting the configuration (like theHttpOptions
class).See #43973
Cache
Provide cache mechanism for each of those extension point:
PropertyListExtractorInterface
only,AttributeListExtractorInterface
cannot have a cache by its volatile natureCache will vary depending on the context, so a context hash mecanism should be provided.
Contracts
Some of the Serializer interfaces may be moved to the
contracts
componentFinal thoughts
We want to tackle a lot of this work during the upcoming Hackthon, and i would like to thanks all people that contribute issues and pull requests on the serializer component.
We try to respect a lot of your work and problems by making this plan, if you think that there is some features missing or some wrong approach, feel free to respond here.
Thanks @soyuka for the review ot this plan.
The text was updated successfully, but these errors were encountered: