.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
- Refit Interfaces: Define API contracts as interfaces.
- Immutable DTOs: Use
recordfor all request/response models. - Resilience: Apply standard resilience handlers (Polly) via DI.
- Typed Clients: Always register clients with
AddRefitClient<T>(). - 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 |
Scan to join WeChat group