Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read
Q&A

How to define Polly policies when working with Refit library in ASP.NET Core?

+0
−0

Note: this is based on my question on SO and subsequent activity there

I am trying to add resilience using Polly to HTTP calls that are performed using Refit library.

I am using the Refit factory method RestService.For<> and I have a working code, but I feel it is way more complex than it should be:

The refit interface

[Headers("Authorization: Bearer")]
public interface IBarIntegration
{
	[Get("/api/ext/Foo/GetFooBriefInfo")]
	Task<ApiResponse<GetFooBriefInfoForFooDto>> GetFooBriefInfo(GetFooBriefInfoForFooInputDto inputData);
}

Factory class that also configures the authentication

internal sealed class BarApiClientHelper : IBarApiClientHelper
{
	private readonly IOptionsSnapshot<BarApiSettings> _BarSettings;
	private readonly IAccessTokenHelperService _accessTokenHelperService;

	public BarApiClientHelper(IOptionsSnapshot<BarApiSettings> BarSettings, IAccessTokenHelperService accessTokenHelperService)
	{
		_BarSettings = BarSettings;
		_accessTokenHelperService = accessTokenHelperService;
	}

	public async Task<TApiClient> CreateApiClient<TApiClient>(CancellationToken token)
	{
		string baseUrl = _BarSettings.Value.BaseUrl;
		string accessToken = await _accessTokenHelperService.GetAccessToken(token);

		var refitClient = RestService.For<TApiClient>(baseUrl, new RefitSettings
		{
			AuthorizationHeaderValueGetter = () => Task.FromResult(accessToken)
		});

		return refitClient;
	}
}

Example call

public async Task<GetFooBriefInfoForFooDto> GetFooBriefInfo(string upn, CancellationToken token)
{
	var apiClient = await _clientHelper.CreateApiClient<IBarIntegration>(token);
	var retrialPolicy = _registry.Get<AsyncRetryPolicy<IApiResponse>>(DefaultRetrialPolicy);

	var func = async () => (IApiResponse) await apiClient.GetFooBriefInfo(new GetFooBriefInfoForFooInputDto { FooContactUpn = upn });
	var FooInfo = (ApiResponse<GetFooBriefInfoForFooDto>) await retrialPolicy.ExecuteAsync(func);
	await FooInfo.EnsureSuccessStatusCodeAsync();

	return FooInfo.Content!;
}
Why does this post require moderator attention?
You might want to add some details to your flag.
Why should this post be closed?

0 comment threads

1 answer

+0
−0

Refit allows such configuration out of the box bt using AddRefitClient (which resembles the well-known AddHttpClient). This indeed requires explicit configuration for the HttpClient, but the configuration and usage will be simpler:

Refit and resilience configuration

private static IServiceCollection ConfigureResilience(this IServiceCollection services)
{
    services
        .AddRefitClient(typeof(IBarIntegration), (sp) =>
        {
            var accessTokenHelperService = sp.GetRequiredService<IAccessTokenHelperService>();
            return new RefitSettings
            {
                AuthorizationHeaderValueGetter = () => accessTokenHelperService.GetAccessToken(default)
            };
        })
        .ConfigureHttpClient((sp, client) =>
        {
            var BarSettings = sp.GetRequiredService<IOptions<BarApiSettings>>();
            string baseUrl = BarSettings.Value.BaseUrl;
            client.BaseAddress = new Uri(baseUrl);
        })
        .AddTransientHttpErrorPolicy(policyBuilder => policyBuilder.WaitAndRetryAsync(   Backoff.DecorrelatedJitterBackoffV2(TimeSpan.FromSeconds(1), RetryPolicyMaxCount)
            )
        );
        .WaitAndRetryAsync(Backoff.DecorrelatedJitterBackoffV2(TimeSpan.FromSeconds(1), RetryPolicyMaxCount)));

    return services;
}

Refit interface

[Headers("Authorization: Bearer")]
public interface IBarIntegration
{
    [Get("/api/ext/Foo/GetFooBriefInfo")]
    Task<GetFooBriefInfoForFooDto> GetFooBriefInfo(GetFooBriefInfoForFooInputDto inputData);
}
Why does this post require moderator attention?
You might want to add some details to your flag.

0 comment threads

Sign up to answer this question »