I’m trying to write an Azure Function that works as a multi-tenant. When a clientId comes from the clients as a parameter, I need to fetch its configuration from Azure App Configuration using labels.
Let me explain in a pseudo code;
I’m using .Net 6 Azure Function Isolated.
I made configuration in Program.cs like in the below code;
new HostBuilder()
.ConfigureAppConfiguration(builder =>
{
string cs = "connection-string"; //which is actually comes from environment veriable
builder.AddAzureAppConfiguration(options =>
{
options.Connect(cs);
//options.Select(KeyFilter.Any, Environment.GetEnvironmentVariable("ClientId")); //It works that way, but I don't want to do it. I need to read the clientId while I receive the request
});
})
Let’s assume that we made a middleware and a request came out
public RequestMiddleware(){
//Here I need to inject some service
}
//Invoke method of middleware
public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next){
HttpRequestData requestData = await context.GetHttpRequestDataAsync();
requestData.Headers.TryGetValues("client-id", out var clientId);
var id = clientId.First();
//And here, I need to configure App Configuration to use the id as a label. As I did in the Program.cs
//like this ; options.Select(KeyFilter.Any, id);
}
Does it possible to load configuration by the label in the request lifecycle? Please keep in mind that Azure App Configuration in the standard tier has a limitation on requests, 3000 per hour. That’s why it won’t be a good idea to load AppConfiguration each time.
2
Answers
What you can do is work with a static Dictionary to ‘cache’ and whenever a request with some new client id arrives, you fetch the configuration add it to the dictionary for the future requests.
This document discussed strategies you should think about when using App Configuration in multi-tenant applications.
https://learn.microsoft.com/en-us/azure/architecture/guide/multitenant/service/app-configuration
From your description, it looks like you want to load tenant-specific config on-demand instead of all at once at the app startup, so you shouldn’t need the code in program.cs. I would recommend using prefixes instead of labels to differentiate the config date for each tenant.
Check out the application-side caching section to learn more what options you have. I imagine, in the middleware, upon every request, you will first check if you have a cached
IConfiguration
instance for the tenant; if not, you will load the config for this tenant and cache it; if yes, you serve the request based on the config in your cache.