What Is HttpClientFactory?
As we all know HttpClient has some serious issues, such as disposing of the HttpClient object doesn’t close the socket immediately; singleton HttpClient instance is not respecting the DNS Time to Live settings, etc.
HttpClientFactory solves the all these problems. It is one of the newest features of ASP.NET Core 2.1. It is an opinionated factory for creating HttpClient instances to be used in your applications.
For more information about HttpClientFactory, please visit its
GitHub page.
Now, let's take a look at how to combine them.
Create An Extension Method
To enable HttpClientFactory when we use WebApiClient, we should add an extension method that returns **IHttpClientBuilder.
And here, we will use the Typed Client of HttpClientFactory.
Here are the samples.
-
-
-
- public static class WebApiClientExtension
- {
-
-
-
-
-
-
-
- public static IHttpClientBuilder AddHttpApiClient<TInterface>(this IServiceCollection services, Action<HttpApiConfig> config = null) where TInterface : class, IHttpApi
- {
- return services.AddHttpClient(typeof(TInterface).Name).AddTypedClient<TInterface>((client, provider) =>
- {
- var httpApiConfig = new HttpApiConfig(client);
- config?.Invoke(httpApiConfig);
- return HttpApiClient.Create<TInterface>(httpApiConfig);
- });
- }
- }
We use client interface's name as the identification of each HttpClient instance.
Interface Declaration
Create a client interface. Here, let us use the sample of the last article.
- public interface IPersonApiClient : IHttpApiClient
- {
- [HttpGet("/api/persons")]
- ITask<List<Person>> GetPersonsAsync();
-
- [HttpGet("/api/persons/{id}")]
- ITask<Person> GetPersonAsync(int id);
-
- [HttpPost("/api/persons")]
- ITask<Person> AddPersonAsync([JsonContent]Person person);
-
- [HttpPut("/api/persons")]
- ITask<string> EditPersonAsync([JsonContent]int id);
-
- [HttpDelete("/api/persons/{id}")]
- ITask<string> DeletePersonAsync(int id);
- }
Configure WebApiClient Interface
Go to Startup class and modify the ConfigureServices mothod so that we can configure our WebApiClient interface.
- public void ConfigureServices(IServiceCollection services)
- {
- services.AddHttpApiClient<IPersonApiClient>(config=>
- {
- config.HttpHost = new System.Uri(Configuration.GetValue<string>("personapi_url"));
- });
- services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
- }
The above code configures
IPersonApiClient and specify the base URL that reads from appsettings.json.
Up to here, we have finished all the configurations. The next step is to call our APIs.
Calling APIs
After the configuration, we can get the API Client Interface using constructor injection.
- [Route("api/[controller]")]
- [ApiController]
- public class ValuesController : ControllerBase
- {
- private readonly IPersonApiClient _api;
-
- public ValuesController(IPersonApiClient api)
- {
- this._api = api;
- }
-
-
- [HttpGet]
- public async Task<List<Person>> GetAsync()
- {
- return await _api.GetPersonsAsync();
- }
-
-
- [HttpGet("{id}")]
- public async Task<Person> GetAsync(int id)
- {
- return await _api.GetPersonAsync(id);
- }
-
-
- [HttpPost]
- public async Task<Person> PostAsync([FromBody] Person value)
- {
- return await _api.AddPersonAsync(value);
- }
-
-
- }
After running up this project, visit `/api/values`. You may get the following result.
Turn to the terminal. We can find that the log message of System.Net.Http.HttpClient contains our client API interface's name. We can use this to distinguish different Client APIs!
Here is the source code you can find in my GitHub page,
Summary
In this article, I showed you how to combine WebApiClient with HttpCLientFactory to call REST APIs that we can use in our .NET Core server-side code.
I hope this article was helpful to you!