前言
在 .NET Core
应用中访问 ASP.NET Core Web API
接口,常用的方式是使用 IHttpClientFactory
生成 HttpClient
实例,并通过结合 Polly 策略,以实现重试,熔断等机制。
Refit 介绍
Refit 是一个类型安全的 REST 开源库,可通过 Refit 更加简单安全地访问 Web API 接口。
首先,需要将 Web API
接口形式转换成 Interface
形式:
1
2
3
4
5
|
public interface IWeatherAPI
{
[Get("/WeatherForecast")]
Task<WeatherForecast[]> Get();
}
|
然后,通过 RestService
类生成 IWeatherAPI
的代理实现,通过代理直接调用 Web API
接口:
1
2
3
|
var weatherAPI = RestService.For<IWeatherAPI>("http://localhost:5000");
var weatherForeCasts = await weatherAPI.Get();
|
结合 Polly
1. 手工执行
可以通过 Policy.ExecuteAsync
方法执行 Web API
调用代码。下列代码实现了重试机制:
1
2
3
4
5
6
7
8
9
|
var weatherAPI = RestService.For<IWeatherAPI>("http://localhost:5000");
var weatherForeCasts = await Policy
.Handle<HttpRequestException>(
ex => ex.InnerException.Message.Any())
.RetryAsync(10, async (exception, retryCount) =>
{
await Console.Out.WriteLineAsync(exception.Message);
}).ExecuteAsync(async () => await weatherAPI.Get());
|
2. 依赖注入(推荐)
更加方便的方式是使用依赖注入的方式,自动将 Refit 和 Polly 结合起来。
首先,引用 Nuget 包:
1
2
3
|
Refit.HttpClientFactory
Microsoft.Extensions.Http.Polly
|
然后,修改 Startup.cs
,注册 RefitClient
,并增加了超时和重试策略:
1
2
3
4
5
6
7
8
9
10
11
12
|
AsyncRetryPolicy<HttpResponseMessage> retryPolicy = HttpPolicyExtensions
.HandleTransientHttpError()
.Or<TimeoutRejectedException>()
.WaitAndRetryAsync(10, _ => TimeSpan.FromMilliseconds(5000));
AsyncTimeoutPolicy<HttpResponseMessage> timeoutPolicy = Policy
.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromMilliseconds(30000));
services.AddRefitClient<IWeatherAPI>()
.ConfigureHttpClient(c => c.BaseAddress = new Uri("http://localhost:5000"))
.AddPolicyHandler(retryPolicy)
.AddPolicyHandler(timeoutPolicy);
|
最后,直接使用 IWeatherAPI
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
private readonly IWeatherAPI _weatherAPI;
public WeatherForecastController(IWeatherAPI weatherAPI)
{
_weatherAPI = weatherAPI;
}
[HttpGet]
public async Task<IEnumerable<WeatherForecast>> Get()
{
var weatherForeCasts = await _weatherAPI.Get();
return weatherForeCasts;
}
|
结论
推荐使用依赖注入方式,简化 Refit
集成 Polly
的操作。
相关链接
https://mp.weixin.qq.com/s/h4LqyLx1VDdwlfS-46NAvg