Back to skills
extension
Category: Development & EngineeringNo API key required

dotnet-refit-http

Use when implementing external API integrations in .NET; when needing typed HTTP clients, resilience (retries, circuit breakers), or structured API error handling.

personAuthor: jakexiaohubgithub

.NET HTTP Communication with Refit & Resilience

Standardized approach for consuming external APIs using Refit and Microsoft.Extensions.Http.Resilience.

Detail Files

| File | Content | |------|---------| | interfaces.md | How to define API contracts, attributes, and return types (ApiResponse<T>). | | usage.md | Best practices for consuming ApiResponse<T>, handling errors, and reading headers. | | resilience.md | Configuring AddStandardResilienceHandler and custom Polly policies. | | dtos.md | Creating immutable record DTOs with proper JSON mapping. | | configuration.md | DI registration, Auth handlers, and RefitSettings. | | testing.md | Patterns for Unit Testing (Moq) and Integration Testing (MockHttp). |

Core Principles

  1. Refit Interfaces: Define API contracts as interfaces.
  2. Immutable DTOs: Use record for all request/response models.
  3. Resilience: Apply standard resilience handlers (Polly) via DI.
  4. Typed Clients: Always register clients with AddRefitClient<T>().
  5. No Exceptions: Prefer ApiResponse<T> over catching exceptions for flow control.

Quick Start

1. Add Packages

dotnet add package Refit.HttpClientFactory
dotnet add package Microsoft.Extensions.Http.Resilience

2. Define the Interface

using Refit;

public interface IExternalUserApi
{
    [Get("/users/{id}")]
    Task<ApiResponse<UserResponse>> GetUserAsync(string id, CancellationToken ct);
}

3. Register in Program.cs

builder.Services
    .AddRefitClient<IExternalUserApi>()
    .ConfigureHttpClient(c => c.BaseAddress = new Uri("https://api.example.com"))
    .AddStandardResilienceHandler();

MANDATORY Checklist

| Component | ✅ DO THIS | ❌ AVOID THIS | |-----------|------------|---------------| | Client | AddRefitClient<T>() | new HttpClient() | | Models | public record Name(string Val); | public class Name { get; set; } | | Resilience | .AddStandardResilienceHandler() | Manual Policy.Handle<T>()... | | Async | Pass CancellationToken | .Result or .Wait() | | Config | BaseAddress in DI | Hardcoded URLs in Client |