HTTP request ihttpclientfactory example in. Net core

Time:2020-5-15

How to use

Ihttpclientfactory has four modes:

  • Basic Usage
  • Named client
  • Typed client
  • Generated clients

Basic Usage

In the startup.configureservices method, you can register the ihttpclientfactory by calling the addhttpclient extension method on iservicecollection


services.AddHttpClient();

After registration, it can be used in the class in the form of constructor injection like dependency injection di. Pseudo code:


class A
{
 private readonly IHttpClientFactory _clientFactory;
 public A(IHttpClientFactory clientFactory)
 {
  _clientFactory = clientFactory;
 }
 
 Public void Use()
 {
   var request=new HttpRequestMessage(HttpMethod.Get,"www.baidu.com") ;
   var client = _clientFactory.CreateClient();
   var response = await client.SendAsync(request); 
   if (response.IsSuccessStatusCode)
   {
   Branches = await response.Content.ReadAsAsync<IEnumerable<GitHubBranch>>();
   }
  else
  {
   GetBranchesError = true;
   Branches = Array.Empty<GitHubBranch>();
  }  
 }
}

Named client

Also add configuration parameters based on basic usage: for example, add a client under Baidu:

services.AddHttpClient("baidu",c=>
{
 c.BaseAddress = new Uri("https://api.baidu.com/");
 //Some other parameters
});

Then, when using, just need to pass the client name to automatically use the basic address configuration of Baidu address:


 var client = _clientFactory.CreateClient("baidu");

Typed client

It is clear that the httpclient type can be directly accepted in the constructor of the used class, instead of being created by the createclient method of the ihttpclientfactory interface, but the first condition is to create the injection type first, and then inject at the same time in the configureservices method:


services.AddHttpClient<classHttp>();

Injection type:

public class classHttp
{
   public HttpClient Client { get; }
   public GitHubService(HttpClient client)
   {
      client.BaseAddress = new Uri("https://api.baidu.com/");
      //Set some other parameters as in configureservices
      Client = client;
   }
}

Generated clients

I personally understand that this is to configure and use the third-party library, and then inject the interface type, in which some method interfaces can be written. The interface is then called directly through the interface class.

Personal understanding: it is similar to an interface mapping and address mapping. By combining with the third-party library (official recommendation of refit) to request an address alias, alias refers to the defined interface. The alias then points back to the real request interface address by adding the attribute get (path) or post (path). The real address of the transformation request is realized through the local interface method of request.

For example, define the interface:


public interface IHelloClient
{
  [Get("/MyInterFace")]
  Task<Reply> GetMessageAsync();
}

To configure the revert plug-in:

Similar to the normal configuration, the service injection of the interface is added later.


public void ConfigureServices(IServiceCollection services)
{
  services.AddHttpClient("hello", c =>
  {
    c.BaseAddress = new Uri("http://localhost:5000");
  })
  .AddTypedClient(c => Refit.RestService.For<IHelloClient>(c));

  services.AddMvc();
}

Then I’ll talk about the get (“/ myinterface”) method on the interface; we don’t need to do another project under the current project, so we can directly create a method named myinterface under the API project.


[ApiController]
public class TestController : ControllerBase
{
   [HttpGet("/")]
  public async Task<sting> MyInterFace()
  {
    return "ceshi";
  }
}

Then you can use the interface:


[ApiController]
public class ValuesController : ControllerBase
{
  private readonly IHelloClient _client;

  public ValuesController(IHelloClient client)
  {
    _client = client;
  }

  [HttpGet("/")]
  public async Task<ActionResult<Reply>> Index()
  {
    return await _client.GetMessageAsync();
  }
}

The _client. Getmessageasync() method here is to call the interface method. It seems that the getmessageasync method is actually to map. The mapping address is the myinterface method written in the above feature. This conclusion can also be verified by breakpoints. Then different projects also have the same meaning. If we request Baidu’s address: www.baidu.com/api/b, this interface

In the configuration, change the request address http://localhost:5000 to www.baidu.com/api, and then change myinterface on the getmessageasync method to B.

Outbound request Middleware

Personal understanding is that the request return preprocessor inherits the delegatinghandler derived class to override the sendasync method. Execute the code before passing the request to the next handler in the pipeline:


public class ValidateHeaderHandler : DelegatingHandler
{
  protected override async Task<HttpResponseMessage> SendAsync(
    HttpRequestMessage request,
    CancellationToken cancellationToken)
  {
    if (!request.Headers.Contains("X-API-KEY"))
    {
      return new HttpResponseMessage(HttpStatusCode.BadRequest)
      {
        Content = new StringContent(
          "You must supply an API key header called X-API-KEY")
      };
    }

    return await base.SendAsync(request, cancellationToken);
  }
}

Then in configureservices:

Services. Addtransient < validateheaderhandler > (); // register handler
services.AddHttpClient("externalservice", c =>
{
  // Assume this is an "external" service which requires an API KEY
  c.BaseAddress = new Uri("https://localhost:5000/");
})
. addhttpmessagehandler < validateheaderhandler > (); / inject into HTTP request pipeline

You can register multiple handlers at the same time.

Httpclient and life cycle

Every time createclient is called on ihttpclientfactory, a new instance of httpclient is returned. Each named client has an httpmessagehandler. The factory manages the lifetime of the httpmessagehandler instance.

Httpclient instance is not destroyed together with httpmessagehandler. Httpmessagehandler exists in the pool. If the life cycle is not reached, it will not be destroyed and will be used by a new httpclient instance.

The default lifetime of the handler is 2 minutes, which can be modified by configuration:


services.AddHttpClient("extendedhandlerlifetime")
  .SetHandlerLifetime(TimeSpan.FromMinutes(5));

summary

The above is the whole content of this article. I hope that the content of this article has some reference learning value for your study or work. Thank you for your support for developepaer.