-
-
Notifications
You must be signed in to change notification settings - Fork 585
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
Don't return a metadata object unless there is explicit annotation or attribute configuration #1494
Don't return a metadata object unless there is explicit annotation or attribute configuration #1494
Conversation
Oh the test failures here are fun 😅 The decorating drivers all have So not only do we have the annotation/attribute drivers always providing a metadata object, we also have decorating drivers which expect non-null returns from the drivers they decorate. |
a3e0da2
to
874250b
Compare
would it be an idea to add a
|
It gets a little more complicated than that, unfortunately. Discriminators won't be built correctly without a metadata object (in any form) being returned. I found this one out the hard way through the tests, the Because the base And, that still doesn't fix the assumptions from the drivers that decorate the annotation/attribute, XML, and YAML chain (i.e. the Doctrine type drivers, the enum driver, or the default value property driver). All of those pretty much hard fail without that chain returning a metadata object (if Even if we sort out the behavior with loading metadata, we still have runtime issues in the graph visitors. Plus, there are still other little oddities floating around. I didn't think this little PR would end up with me digging deep into a rabbit hole, but at least I have a cozy little corner dug out now 🤣 |
a41e7cd
to
111e02f
Compare
0bb46ad
to
26c481f
Compare
@mbabker to me this looks good. should now the |
can you also put a warning on the documentation saying that doctrine/annotations is needed to use annotations, and that attributes are the default? |
It sounds like a BC change for some users 🤔 |
We're not quite there yet. This and #1471 in theory would make it possible to not hard require annotations, but as long as the builder API hard requires an annotation reader then that's a premature move.
IMO it's easily called out in the upgrade notes. And for me personally, this is one of those cases where if you're relying on transient dependencies to install the packages your application has a hard requirement on, you're better off taking the 2 minutes to run the appropriate |
26c481f
to
ee9acb1
Compare
… attribute configuration, add the NullDriver to the default driver chain to ensure a minimally configured metadata object is created
ee9acb1
to
14531d9
Compare
BTW, if anyone's got any ideas on the failing CS checks, I'm all eyes. I've tried use statements (which failed because the sniffer decided they were unused) and just dumping FQCN's into the attributes (causing the current failures) and I haven't found something that satisfies PHP_CodeSniffer. |
It looks like the issue is with super outdated Code Sniffer. I've added MR to update it to 12.x - that understands annotations :) |
@goetas Dragging #1497 (review) over here...
Yes, but this should be very low impact (the null driver isn't actually used anywhere in the package or Symfony bundle at the moment, so this would only affect folks who are using their own driver factories to build serializers and not in the context of a Symfony app). The reason it's needed is because anything that would fall back to the null driver would produce object keys that do not respect the configured naming strategy, so the keys would always be as declared in the data source. This is also a by-product of making the null driver include all the class properties instead of only creating a metadata object with a file resource reference; this matches up with the behavior that exists now when "empty" metadata objects are created by the annotation/attribute drivers for classes without that metadata.
So this is the hidden gotcha I got into in #1494 (comment) where basically the annotation/attribute driver will always create and return an empty metadata object even if the class it's processing doesn't have any annotations/attributes to create any metadata from, whereas the XML and YAML drivers will only create metadata objects if there is a corresponding metadata configuration. So this change makes the behavior for all of the metadata-based drivers consistent in that they only provide a metadata instance if there is metadata to generate it from, and the fallback behavior is moved out of the annotation/attribute drivers and into the null driver. |
Only after mergeing this I realized a thing... In the bundle, that is not using the null driver, is this now going to stop serializing objects that have no annotations defined? |
Yes, the bundle will need an update. Shipping a combination of this and #1471 warrants a major version bump since there are a few B/C breaks in the internal APIs. I'll have a PR put together for the bundle in the next few days to make all the needed changes. |
If I understand the comments here correctly, currently it is normal that we run under |
If Sulu's just using the JMSSerializerBundle, then the Sulu AdminBundle fails/errors look like expected side effects of this PR without the bundle having been updated. |
@alexander-schranz schmittjoh/JMSSerializerBundle#933 would be the bundle changes if you're able to test that with Sulu. Everything's compiling and serializing right in the test app I'm running, but it's not really a great test environment for more than making sure the container's dumped with the right services. |
#1506 is here to minimize this bc break |
Before #1469 the annotation driver would always return a
JMS\Serializer\Metadata\ClassMetadata
regardless of whether the object had any configured annotations or attributes. With the changes in #1469, the new attribute driver inherited the same behavior. And with schmittjoh/JMSSerializerBundle#920 prioritizing the attribute driver over the annotation driver, the end result is now that the attribute driver will always return a metadata object even if there were no attributes on the object and the chain will never fall through to a later driver (in this case, the annotation driver).Untested, but this should change the behavior for these two drivers so that it returns null if there are no explicitly configured annotations or attributes on an object instead of a metadata object without any information. The toggle on whether to return the metadata object or null is based solely on the presence of annotations or attributes; once the code gets into the loops processing those, we'll assume there is a configuration that should be used (as those loops won't be entered for empty lists).
I mark this as "maybe" a B/C break because it's really a weird edge case.
Metadata\Driver\DriverInterface::loadMetadataForClass()
supports null returns, which are accounted for already in the metadata package, but there is a change in runtime behavior in that a metadata instance will no longer be provided on objects that never had configuration in the first place. If someone's relying on this behavior, they might be in for an unwelcome surprise on upgrade.