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

Deserialize configuration settings with JSON content type #191

Closed
avanigupta opened this issue Jul 24, 2020 · 16 comments · Fixed by #181
Closed

Deserialize configuration settings with JSON content type #191

avanigupta opened this issue Jul 24, 2020 · 16 comments · Fixed by #181
Assignees
Labels
breaking change enhancement New feature or request

Comments

@avanigupta
Copy link
Member

avanigupta commented Jul 24, 2020

Overview

In order to preserve data types of non-string values in App Configuration, the "Content Type" property of settings can be leveraged. If a setting in App Configuration has a valid JSON content type and a valid JSON value, it should be deserialized by the Configuration Provider.

Scope of Breaking Change

If your App Configuration store already has key-values with valid JSON content type and valid JSON value, your application might be affected by this change.
For example, if you have this key-value in AppConfiguration:

{
  "contentType": "application/json",
  "key": "Foo",
  "label": null,
  "value": "[1,2,3]"
}

Currently, you might be accessing this setting in your application directly with the key name, like config["Foo"]. But with this new feature, your value will be deserialized and config["Foo"] will be null. You will now have to access config["Foo:0"], config["Foo:1"] and config["Foo:2"] in your application.
To avoid application failures, update the content type of your key-values in AppConfiguration or the application code to handle the deserialized key-values.

Valid JSON Content Type

Media types, as defined here, can be assigned to the Content Type field in App Configuration.
A media type consists of a type and a subtype, which is further structured into a tree. A media type can optionally define a suffix and parameters:

type "/" [tree "."] subtype ["+" suffix] *[";" parameter]

If the type is "application" and the subtype (or suffix) is "json", the media type will be considered a valid JSON type.
Some examples of valid JSON types are:

  • application/json
  • application/activity+json
  • application/vnd.foobar+json;charset=utf-8

Valid JSON Values

If the value of a configuration setting can be validated using any JSON validator (like JSONLint), it can be deserialized correctly by the Configuration Provider. If a configuration setting has valid JSON content type, but its value is not valid JSON, no deserialization will be performed and it will be treated like a string value.
Some examples of valid JSON values are:

- "This is some text"
- 723
- false
- null
- "2020-01-01T12:34:56.789Z"
- [1, 2, 3, 4]
- {"ObjectSetting":{"Targeting":{"Default":true,"Level":"Information"}}}

Sample JSON settings in App Configuration

image

@avanigupta avanigupta added enhancement New feature or request breaking change labels Jul 24, 2020
@avanigupta avanigupta added this to the v4.0.0-preview milestone Jul 24, 2020
@avanigupta avanigupta self-assigned this Jul 24, 2020
@avanigupta avanigupta linked a pull request Jul 24, 2020 that will close this issue
@BlowaXD
Copy link

BlowaXD commented Jul 24, 2020

Hello,

Any date planned for the release ?

@avanigupta
Copy link
Member Author

Hi @BlowaXD , the preview version of this change has already been released. You can find the packages here:

Please let us know if you have any feedback as that would help us release the stable version soon.

@mwoo-o
Copy link

mwoo-o commented Mar 17, 2022

Hello,
I have an Azure App Configuration that contains a key with content type of "Application/json".
How to find out the Content type of a key?
I see that there is Azure.Data.AppConfiguration.ConfigurationSetting class that can indicate the Content type of a Key.
However, how should we get the ConfigurationSetting from IConfiguration or Microsoft.Extensions.Configuration.ConfigurationRoot? Is it possible to do that?

@avanigupta
Copy link
Member Author

Hello @mwoo-o, if you're using the AppConfig provider library (Microsoft.Extensions.Configuration.AzureAppConfiguration) to read your key-values from Azure App Configuration, we will automatically deserialize the key-values with content type "application/json" before adding them to IConfiguration. Since IConfiguration is just a collection of key-value pairs, we cannot provide all the information of a ConfigurationSetting in IConfiguration.
Could you explain your scenario a bit so that I can understand why you want to access the ConfigurationSetting from IConfiguration?

@mwoo-o
Copy link

mwoo-o commented Mar 21, 2022

In our scenario, if application provides our provider key, says key1, in the App configuration, we are thinking to process the key1's value based on the content type. The key value doesn't need to be only Json. It can be xml or format that are understood by our provider. We are in the process of exploring different possibilities.

For example, If it is Json, then we can deserialize the Json value using the
ConfigurationBinder.Bind(azConfig, , );

Having the class to mange it internally in our layer can provide a centralized implementation for us to work with application on premise or in cloud.

@avanigupta
Copy link
Member Author

Thanks for the explanation! We are working on a new API that will allow you to do this in future: #157
Let me know if this would work for you.

@mwoo-o
Copy link

mwoo-o commented Mar 21, 2022

The new API seems to be the solution. Is the new API available?

@avanigupta
Copy link
Member Author

Thanks for confirming. The Map API is still under development, and we are planning to release it with the next version.

@mwoo-o
Copy link

mwoo-o commented Mar 21, 2022

That's great! Will we be notified when the new API is released?

@mwoo-o
Copy link

mwoo-o commented Mar 21, 2022

One more question, Will the new Map API applied to all the Labels for the particular settings?

@avanigupta
Copy link
Member Author

That's great! Will we be notified when the new API is released?

Yes, we'll update the linked github issue when its released.

Will the new Map API applied to all the Labels for the particular settings?

We will let the user transform all ConfigurationSettings retrieved from Azure App Configuration service. But the user is responsible for selecting which ConfigurationSettings will be retrieved from the server. For this, you can use the Select API to specify which keys/labels you want to load (docs).

@mwoo-o
Copy link

mwoo-o commented Mar 21, 2022 via email

@avanigupta
Copy link
Member Author

This is the intended behavior while selecting key-values from AppConfig. The Select API accepts prefix filtering for keys only. We don't support loading all labels at once. This is because if the same key exists for multiple labels, the final value of that key in IConfiguration will be ambiguous. If you want to load multiple labels, you can have multiple Select statements for each label that you want to load. This way, you define the explicit order in which values will be overridden if one key is loaded with multiple labels. For example, you can specify the following:

 var configurationBuilder = new ConfigurationBuilder()
                .AddAzureAppConfiguration(options =>
                {
                    options.Connect(new Uri("https://*****.azconfig.io"), new DefaultAzureCredential())
                           .Select(KeyFilter.Any, myLabel1)
                           .Select(KeyFilter.Any, myLabel2);
                });

If a key exists for both selected labels, its value corresponding to myLabel2 will be used in IConfiguration.

@mwoo-o
Copy link

mwoo-o commented Mar 21, 2022 via email

@avanigupta
Copy link
Member Author

Might be the REST API supports the behavior that I want, but not the Azure API using AzureAppConfigurationOptions.

That is correct. The App Config provider library offers a layer of abstraction over the underlying REST APIs.

I agree with you with the ambiguous scenario when the same key exists for multiple labels. But if there is only one key that exists in a label, there is no ambiguity.

Agreed, but this is something that can only be determined at runtime. If someone unknowingly adds the same key with multiple labels, any application referencing that key will be in an unpredictable state. We want to make sure that this can never happen and users explicitly provide the labels that their app needs.

@mwoo-o
Copy link

mwoo-o commented Mar 22, 2022

The behavior sounds reasonable. At the meanwhile, I don't see any issue.
Thanks for the information.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants