Skip to content
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

NestedJsonProvider: unable to omit empty nested field #764

Open
brenuart opened this issue Mar 7, 2022 · 3 comments
Open

NestedJsonProvider: unable to omit empty nested field #764

brenuart opened this issue Mar 7, 2022 · 3 comments

Comments

@brenuart
Copy link
Collaborator

brenuart commented Mar 7, 2022

Most JsonProviders omit writing their field(s) if their value is null (absent). This is however not the case for the NestedJsonProvider. Consider the following configuration:

<providers>
   <nestedField>
      <fieldName>nested</fieldName>
      <providers>
         <mdc/>
      </providers>
   </nestedField>
</providers>

This configuration produces a JSON similar to the following:

{
   "nested": {
      "mdc1": "value1",
      "mdc2": "value2"
   }
}

However when not MDC keys are present or if none matches the include pattern of the MDC json provider, the "nested" object becomes empty and the output looks as follows:

{
   "nested": {
   }
}

There is unfortunately no option to omit the nested object when it is empty similar to what is available to the PatternJsonProvider.

@brenuart
Copy link
Collaborator Author

brenuart commented Mar 7, 2022

As proposed in this discussion, an option is to decorate the JsonGenerator to make it filter empty fields. This option would be controlled by a new omitEmptyField configuration property added to the LoggingEventCompositeJsonEncoder. The behaviour would be global and would affect all configured JsonProviders.

Most JsonProvider already omit their fields when they are empty and this behaviour is not configurable (cannot be disabled). Adding a new omitEmptyField global option to the JsonCompositeEncoder may be confusing especially when set to false: people may think that the providers will now output their fields with a null value - which won't be the case unless the implementation is changed.

Instead of adding this feature to the CompositeJsonEncoder we could also limit it to the NestedJsonProvider. In this case the semantic must be clarified:

  • should the "nested" field be omitted when its value is empty (i.e. an empty object)
  • or do we want this behaviour to propagate to the nested providers as well?

My feeling is when people want to filter out empty properties, they probably want it everywhere and not limited to only a few properties. Adding a global option affecting all properties would be very convenient and easy to understand. I would also enable this option by default and make sure all providers comply to it (i.e. make them output a null value instead of omitting their properties as they do currently if this new property is set to false).

@philsttr What's your opinion?

@brenuart brenuart changed the title NestedJsonProvider - unable to omit empty nested field NestedJsonProvider: unable to omit empty nested field Mar 9, 2022
@philsttr
Copy link
Collaborator

Hmm. Brainstorming here...

What about having a global omitEmptyFields boolean property on the encoder honored by all providers, but also being able to be overridden on individual providers?

Maybe something like this:

  • Add a global omitEmptyFields Boolean property on the encoder, with possible values true, false, and null/unset (the default).
  • Also add omitEmptyFields Boolean property on the providers as appropriate, with possible values true, false, and null/unset (the default)

The null/unset values mean behave exactly as they do today. And since the default is null/unset, the behavior is fully backwards compatible with how things work today.

When a provider is contributing to the generator,

  • if the provider-level value is set, then honor it.
  • else if the global-level value is set, then honor it
  • else do whatever the current behavior of the provider is ("backwards compatible mode")

Not sure how easy that would be to implement. The providers would need to be able to change the "state" of the token filter before/after the provider contributes to the generator.

My main reasoning for proposing the above is to be able to keep backwards compatibility, while also adding cool new features. Without the null/unset option, and just providing a true/false option, backwards compatibility is broken no matter if the default value is true or false, since neither represents the current behavior. And there would be no way to "revert" to the current behavior.

Alternatively, just implementing a new omitIfEmpty option on the NestedJsonProvider that only applies to the nested object itself (not the sub-providers), with a default value of false, is a much more targetted and simpler approach. I'd be ok doing this as a simple solution first. And then coming back later to try to do the more complex global solution.

@dtanner
Copy link

dtanner commented Mar 22, 2023

As a consumer,

just implementing a new omitIfEmpty option on the NestedJsonProvider that only applies to the nested object itself

would work fine for me. In my normal configuration use case, I'm only adding a single nestedField, so config duplication isn't a concern.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants