Combine WebApiClient With HttpClientFactory To Call REST APIs

This article introduced how to combine WebApiClient with HttpCLientFactory to call REST APIs that we can use in our .NET Core server-side code.

Introduction

In my last article, we discussed how to use WebApiClient to call REST APIs in ASP.NET Core. Now, in this article, we will discuss how to combine WebApiClient with HttpClientFactory to call REST APIs.  

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.
  1. /// <summary>  
  2. /// WebApiClient extension.  
  3. /// </summary>  
  4. public static class WebApiClientExtension  
  5. {  
  6.     /// <summary>  
  7.     /// Adds the http API client.  
  8.     /// </summary>  
  9.     /// <returns>The http API client.</returns>  
  10.     /// <param name="services">Services.</param>  
  11.     /// <param name="config">Config.</param>  
  12.     /// <typeparam name="TInterface">The 1st type parameter.</typeparam>  
  13.     public static IHttpClientBuilder AddHttpApiClient<TInterface>(this IServiceCollection services, Action<HttpApiConfig> config = null) where TInterface : class, IHttpApi  
  14.     {  
  15.         return services.AddHttpClient(typeof(TInterface).Name).AddTypedClient<TInterface>((client, provider) =>  
  16.         {  
  17.             var httpApiConfig = new HttpApiConfig(client);  
  18.             config?.Invoke(httpApiConfig);  
  19.             return HttpApiClient.Create<TInterface>(httpApiConfig);  
  20.         });  
  21.     }  
  22. }  
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.
  1. public interface IPersonApiClient : IHttpApiClient  
  2. {  
  3.     [HttpGet("/api/persons")]  
  4.     ITask<List<Person>> GetPersonsAsync();  
  5.   
  6.     [HttpGet("/api/persons/{id}")]  
  7.     ITask<Person> GetPersonAsync(int id);  
  8.   
  9.     [HttpPost("/api/persons")]  
  10.     ITask<Person> AddPersonAsync([JsonContent]Person person);  
  11.   
  12.     [HttpPut("/api/persons")]  
  13.     ITask<string> EditPersonAsync([JsonContent]int id);  
  14.   
  15.     [HttpDelete("/api/persons/{id}")]  
  16.     ITask<string> DeletePersonAsync(int id);  
  17. }  
Configure WebApiClient Interface 
 
Go to Startup class and modify the ConfigureServices mothod so that we can configure our WebApiClient interface.
  1. public void ConfigureServices(IServiceCollection services)  
  2. {  
  3.     services.AddHttpApiClient<IPersonApiClient>(config=>  
  4.     {  
  5.         config.HttpHost = new System.Uri(Configuration.GetValue<string>("personapi_url"));  
  6.     });  
  7.     services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);  
  8. }  
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.
  1. [Route("api/[controller]")]  
  2. [ApiController]  
  3. public class ValuesController : ControllerBase  
  4. {  
  5.     private readonly IPersonApiClient _api;  
  6.   
  7.     public ValuesController(IPersonApiClient api)  
  8.     {  
  9.         this._api = api;  
  10.     }  
  11.   
  12.     // GET api/values  
  13.     [HttpGet]  
  14.     public async Task<List<Person>> GetAsync()  
  15.     {  
  16.         return await _api.GetPersonsAsync();  
  17.     }  
  18.   
  19.     // GET api/values/5  
  20.     [HttpGet("{id}")]  
  21.     public async Task<Person> GetAsync(int id)  
  22.     {  
  23.         return await _api.GetPersonAsync(id);  
  24.     }  
  25.   
  26.     // POST api/values  
  27.     [HttpPost]  
  28.     public async Task<Person> PostAsync([FromBody] Person value)  
  29.     {  
  30.         return await _api.AddPersonAsync(value);  
  31.     }  
  32.   
  33.     //....  
  34. }  
After running up this project, visit `/api/values`. You may get the following result.
 
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!
 
client API
 
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!