I am working on .net core web app which needs to call remote APIs at specific intervals(every 2 mins, 20 different API calls & I need to show API results to end users), hosted with 4 different domain names
I used HttpClient to call remote APIs. But with increased users, my CPU usage increased up to 40%. I suspect HttpClient might be the reason. After going through few blogs, I am trying to use HttpClientFactory.
I have a single method which gets call from Controller Action & I need to dynamically identify the BaseUrl based on few parameters. Currently I have created 4 NamedClients in StartUp.cs like this:
services.AddHttpClient(ApiConfig.NamedHttpClients.TestUrl1, client =>
{
client.BaseAddress = new Uri(Configuration.GetSection("BaseUrls").GetSection("TestUrl1").Value);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("Authorization", "Basic " + ApiConfig.GetEncodedCredentials(Configuration));
var userAgent = "C# app";
client.DefaultRequestHeaders.Add("User-Agent", userAgent);
}).SetHandlerLifetime(TimeSpan.FromMinutes(5));
services.AddHttpClient(ApiConfig.NamedHttpClients.TestUrl2, client =>
{
client.BaseAddress = new Uri(Configuration.GetSection("BaseUrls").GetSection("TestUrl2").Value);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("Authorization", "Basic " + ApiConfig.GetEncodedCredentials(Configuration));
var userAgent = "C# app";
client.DefaultRequestHeaders.Add("User-Agent", userAgent);
});
And then using in class like this:
public class Service : IService
{
private readonly IHttpClientFactory httpClientFactory;
public Service(IHttpClientFactory clientFactory)
{
httpClientFactory = clientFactory;
}
public HttpResponseMessage GetApiClientResponse(string displayName, IConfiguration configuration, HttpRequest httpRequest)
{
var endPoint = ApiConfig.GetApiDetail(configuration).
SingleOrDefault(ep => ep.DisplayName.ToLower().Equals(displayName.ToLower()));
var client = httpClientFactory.CreateClient(endPoint.NamedClient);
HttpResponseMessage response = null;
try
{
response = client.GetAsync(new Uri(endPoint.EndPointName,UriKind.Relative), HttpCompletionOption.ResponseHeadersRead).Result;
}
catch { ...}
return response;
}
}
here, based on the displayname parameter, I can decide which NamedClient is to be used.
Is there any other efficient way to achieve required functionality? Can I use TypedClient instead?