Named Http Clients In .NET Core Web Applications
Post for HttpClient named instance

Named Http Clients In .NET Core Web Applications

In last article, we have seen a basic example showing how http client middleware can be used to create an HttpClient instance using IHttpClientFactory. In this article, we will see an example of what named http clients are and how they can be used.

Why ?

IHttpClientFactory provides a single place for providing and configuring a logical HttpClient instance. Each HttpClient instance encapsulates the configurations required for HTTP communication (e.g. headers, stream vs buffer mode, etc.).

For calling any APIs, generally there are few settings which are required. For example, if the API is subscription based, then it might be a requirement to send the API key in request headers.

So, every time an HttpClient instance is created, as a developer, we need to set few properties before making the request. If this code is going to be scattered at multiple places, then you might want to have a single place where all these settings can be set. This can be achieved by using the Http Client middleware.

How ?

AddHttpClient provides a way to centralize all the HTTP client configurations at one place. Named clients are a good choice when:

Using the middleware, we can name an HTTP instance, and for every named instance, additional configurations can be specified.

Below code example shows, how GitHub API can be called using named HttpClient instance. A base address and request headers are configured for the named instance.

Next, when the IHttpClientFactory is injected in any class, the name of the instance can be passed to CreateClient method to get HttpClient instance, with all the the intended settings.

// Startup.cs
public class Startup
{
// Some code…
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient("github", c =>
{
c.BaseAddress = new Uri("https://api.github.com/");
// Github API versioning
c.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
// Github requires a user-agent
c.DefaultRequestHeaders.Add("User-Agent", "theCodeBlogger.com Demo");
});
services.AddControllersWithViews();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// Request process pipeline…
}
}
// HomeController.cs
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly IHttpClientFactory _clientFactory;
public HomeController(ILogger<HomeController> logger, IHttpClientFactory clientFactory)
{
_logger = logger;
_clientFactory = clientFactory;
}
public async Task<IActionResult> Index()
{
// URL not specifying base address and no request headers
var request = new HttpRequestMessage(HttpMethod.Get,
"/repos/dotnet/AspNetCore.Docs/branches");
// Create HttpClient by providing name
// Use same name which is used while configuring CreateClient
var client = _clientFactory.CreateClient("github");
var response = await client.SendAsync(request);
if (response.IsSuccessStatusCode)
{
using var responseStream = await response.Content.ReadAsStreamAsync();
dynamic branches = await JsonSerializer.DeserializeAsync
<IEnumerable<dynamic>>(responseStream);
}
else
{
// Error Handling
}
return View();
}
}
view raw Startup.cs hosted with ❤ by GitHub

Opinion

I think this method may prove useful in some situations. It might reduce some duplication of code. Also, all required http communication can be configured at a single place using the http client middleware.

The only thing that might not be ideal is – use of string- for specifying name and for getting the instance of HttpClient. But, a constant can be used to make sure there are no runtime errors due to spelling mistakes / variations.

Are you going to use this in any of your project ? Let me know your thoughts.

Leave a Reply