Configuration quoted and unquoted map keys #55483
Replies: 3 comments 13 replies
|
I know it's a relatively massive breaking change but I would be in favor of having a clear and distinctive format for maps. The fact that the current behavior is ambiguous has come with so many issues. Given we started with quotes, I would go with quotes - as long as it solves the problems we had a long the way with the syntax being unclear (typically the lookup optimizations). Now just to reiterate, that would be a relatively massive breaking change. But I think the config machinery will be able to tell people that the elements are not used? And maybe if we get unused elements, we could check if they match a quoted path in a slow path and provide a nice warning message guiding the user? /cc @geoand @cescoffier |
|
This is a parsing problem, really, and one that the proposed hierarchical design was supposed to solve by semantically interpreting ambiguous segments at the config source level. To me, the expected behavior would be that I can use whatever syntax I like, but if I have a conflicting key in the same file, then I should get a warning or (better yet) an error when that file is loaded. First one wins, second one is rejected loudly. There are a lot of reasons why this might be hard with the current implementation. With a hierarchical config source design, everything would be handled segment-wise, so it should be much easier (and should resolve several issues where maps and non-maps behave differently, which has always been a problem). I don't know where I'm going with this, other than just putting out my opinion (once again) that every second we spend trying to get the original implementation to somehow fit the newer requirements - instead of burning it all down and starting from scratch, which is probably much easier - is another second wasted. If we did this two years ago we'd have been done a year and a half ago and working on much more interesting things. |
Uh oh!
There was an error while loading. Please reload this page.
When a map key does not contain dots, it can be written in both quoted and unquoted forms:
or
Both forms are valid and equivalent for simple keys (no dots). However, when both forms are present in the configuration for the same logical key, properties from one form are silently lost:
Instead of producing one map entry with both url and timeout populated, only properties from one notation are bound. The other form's values are silently ignored, and which form wins depends on iteration order, hence our recommendation to use the same form: https://smallrye.io/smallrye-config/Latest/config/mappings/#maps.
Root Cause
There is a mismatch between how property names are compared and how map keys are extracted:
map.key.urlandmap."key".urlas two different names — quotes are only significant when the key contains dots.When building a map with a complex value type (a nested object), the code commits to one path form per key and constructs the nested object in a single pass using that path. Properties defined with the other form are never found because the property name comparison considers them different.
In many cases, extensions generate additional configurations that may not follow the user syntax (usually, we don't add quotes to single names, but the user may use them).
Comparison with Spring Boot
Spring Boot uses bracket notation (
map[key].url) instead of quotes. For simple keys, bothmap.key.urlandmap[key].urlare valid. When mixed for a complex object, Spring also binds properties from only one notation — the other is silently ignored. However, Spring's behavior is deterministic (bracket notation takes precedence), while in SmallRye Config the result depends on property name iteration order.Possible Solutions
Multiple Quarkus extensions have independently worked around this at the extension level:
Ideally, this should be fixed in SmallRye Config directly:
Unfortunately, I don't see any other solution than a fallback lookup. I've always refrained from implementing it, because it would potentially cause an explosion of lookups, as explained here: #52690 (comment).
The only other solution I see is to force the use of quotes (or even brackets) on any
Mapsegment, either simple or composed. This actually has the benefit of visually making it clear that a specific segment of a configuration is actually a user-defined name (or dynamic name).Related
All reactions