In this article, we are going to learn about HttpClient policies like retry policy, circuit breaker policy.
Retry Policy:
By using HttpClientFactory it is very easy to configure the retry calls. We can configure the retry count. So if an HTTP call fails and if we configured our retry policy then the framework will automatically attempt to retry HTTP call up to the specified retry count number.
Circuit Breaker Policy:
The circuit breaker policy prevents our application to perform the operation that is likely to fail. An application can use both Retry Policy and Circuit Breaker Policy.
Let's understand the circuit breaker policy flow:
- Assume like in our application configured retry policy. Retry policy should have like count for retires and timespan between each retry.
- Next circuit breaker policy configured with 2 parameters like count and timespan. If the number of consecutive HTTP failed calls count matches with the circuit breaker policy count then the circuit will open means subsequent requests or retry won't invoke Http Call they simply return the error message to the user directly. If we want we can write middleware to format the error response from the circuit breaker. The timespan parameter in the circuit breaker defines the period of the circuit opened.
- After circuit timespan parameter time completed, then the circuit will be closed and flow will repeat.
Create .Net5 Web APIs:
For our demo purpose let's create 2 .Net5 Web API projects. Name them like 'MasterAPI' and 'ClienAPI'. By default, the Web API project template contains whether forecast endpoint. So our goal is to consume the 'MaserAPI' endpoint by our 'ClientAPI'. Since dotnet application locally by default run under ports like '5001' and '5000', so for 'MasterAPI' change them to '6001' and '6000'.
Typed Client:
Either using Typed Client or Named Client techniques of HttpClient only can be configured with Retry or Circuit Breaker policies. So here I'm going to create a Typed Client in the 'ClientAPI' project to consume the endpoint from 'MaserAPI'.
Now create a Typed Client class and name it as 'TestClient.cs' and here implement our logic to fetch the data from the 'MasterAPI' endpoint.
ClientAPI/TestClient.cs:
using System.Collections.Generic; using System.Net.Http; using System.Net.Http.Json; using System.Threading.Tasks; namespace ClientAPI { public class TestClient { private readonly HttpClient _httpClient; public TestClient(HttpClient httpClient) { _httpClient = httpClient; } public async Task<List<WeatherForecast>> GetWeather() { return await _httpClient.GetFromJsonAsync<List<WeatherForecast>>("WeatherForecast"); } } }Now register our Typed Client in 'Startup.cs'
Startup.cs:
services.AddHttpClient<TestClient>(client => { client.BaseAddress = new Uri("https://localhost:6001"); }) .SetHandlerLifetime(TimeSpan.FromMinutes(5));
- Registered base domain for our Typed Client.
- Lifetime for HttpClient instance set to 5 minutes.
Controllers/TestController.cs:
using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; namespace ClientAPI.Controllers { [ApiController] [Route("[controller]")] public class TestController : ControllerBase { private readonly TestClient _testClient; public TestController(TestClient testClient) { _testClient = testClient; } [HttpGet] [Route("weather")] public async Task<IActionResult> GetWeatherAsync() { return Ok(await _testClient.GetWeather()); } } }Now run both 'MasterAPI' and 'ClientAPI' projects. The result of 'ClientAPI' looks as below.
Install Polly Library:
To register policies we have to install a Microsoft extension library. We have to install this library in our 'ClientAPI' project
Package Manager: Install-Package Microsoft.Extensions.Http.Polly -Version 5.0.1
.Net CLI dotnet add package Microsoft.Extensions.Http.Polly --version 5.0.1
Configure Retry Policy:
Now in the 'ClientAPI' project, we are going to register Retry Policy to our Typed Client(TestClient.cs).
Let's create a static method of our retry policy in 'Startup.cs'
Startup.cs:
private static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy() { return HttpPolicyExtensions .HandleTransientHttpError() .WaitAndRetryAsync(5, retryAttempt => TimeSpan.FromSeconds(10)); }
- Here our policy is like on HTTP call error, the application has to retry the HTTP calls for '5' times of an interval of 10 seconds on each failure.
Startup.cs:
services.AddHttpClient<TestClient>(client => { client.BaseAddress = new Uri("https://localhost:6001"); }) .SetHandlerLifetime(TimeSpan.FromMinutes(5)) .AddPolicyHandler(GetRetryPolicy());Now to test this Http calls retry, stop running the 'MasterAPI' and then run the 'ClientAPI'.Here we can observe the HTTP calls retry. Once the retry count registered in policy exceeded then the application returns the error message to users.
Configure Circuit Breaker Policy:
Now in our 'ClientAPI' project, we will register one more policy called Circuit Breaker Policy. Circuit Breaker Policy breaks or opens the flow which means the subsequent request will receive an error message from the circuit breaker as a response without invoking the HTTP call. This will very helpful in some cases like our third-party API if they down instead of invoking them every time circuit breaker will give the error response without invoking the HTTP call for a specified amount of time, this approach will help to boost our application.
Now let's create a static method in 'Startup.cs' that implements Circuit Breaker Policy.
Startup.cs:
private static IAsyncPolicy<HttpResponseMessage> GetCircuitBreakerPolicy() { return HttpPolicyExtensions .HandleTransientHttpError() .CircuitBreakerAsync(3, TimeSpan.FromMinutes(1)); }
- Here Circuit Breaker will opens or breaks after 3 consecutive errors, so the next subsequent request will receive an error response directly from Circuit Breaker without invoking HTTP call, this will continue till the time specified, here in our sample we specified 1 minute.
- So for this 1-minute Circuit Breaker in opening or breaking state, once this time is finished then Circuit Breaker will close and the immediate next request will invoke the HTTP calls.
Startup.cs:
services.AddHttpClient<TestClient>(client => { client.BaseAddress = new Uri("https://localhost:6001"); }) .SetHandlerLifetime(TimeSpan.FromMinutes(5)) .AddPolicyHandler(GetRetryPolicy()) .AddPolicyHandler(GetCircuitBreakerPolicy());Now to test the circuit breaker, let's stop running 'MasterAPI', then run our 'ClientAPI'.
Now request 'ClientAPI', since we have registered retry policy, our request will be automatically retiring the HTTP call on every failure.
Now on completion of 3 failure HTTP calls continually, the Circuit Breaker will open or breaks the follow and returns the error response to the client. This opening or breaking state will remains for 1-minute as we specified.
Now in another browser tab request API again, then you can observe you will receive an error immediately from the circuit breaker without invoking HTTP call.
So that all about the register Retry and Circuit breaker policies for HttpClient.Video Session:
Support Me!
Buy Me A Coffee
PayPal Me
Wrapping Up:
Hopefully, I think this article delivered some useful information on HttpClient Policies like Retry and Circuit Breaker. I love to have your feedback, suggestions, and better techniques in the comment section below.
Comments
Post a Comment