Search code examples
c#blazordotnet-httpclientpollyrefit

How to use Polly with Refit?


I am not configuring my Refit client using the services in Startup. I am doing the following:

public Task<IMyService> GetService()
{
    var retryPolicy = HttpPolicyExtensions
        .HandleTransientHttpError()
        .Or<TimeoutRejectedException>()
        .WaitAndRetryAsync(2, _ => TimeSpan.FromMilliseconds(500));

    var timeoutPolicy = Policy
        .TimeoutAsync<HttpResponseMessage>(TimeSpan.FromMilliseconds(500));

    return Task.FromResult(RestService.For<IMyService>(new HttpClient((DelegatingHandler)myHandler)
    {
        BaseAddress = new Uri(myUrl)
    },
        new RefitSettings() {}
    ));
}

I need to add the Polly policies to the client. How can I do this when creating a client with RestService.For<>?


Solution

  • Usually whenever you register a named/typed HttpClient which is decorated with a Polly policy (or chain of policies) then you do that like this

    .AddHttpClient<XYZ>()
    .AddPolicyHandler(...); 
    

    The AddPolicyHandler registers a PolicyHttpMessageHandler with the specified Polly policy. (ref)

    So, you can do the same here:

    var combinedPolicy = Policy.WrapAsync(retryPolicy, timeoutPolicy);
    var outerHandler = new PolicyHttpMessageHandler(combinedPolicy);
    outerHandler.InnerHandler = (DelegatingHandler)myHandler;
    

    Then you can use the outerHandler in your RestService.For call

    RestService.For<IMyService>(new HttpClient(outerHandler))
    

    I haven't tested it but the runtime might require you to set the most inner handler to a new HttpClientHandler to work properly.