Refit pour C# (.NET) : client REST type-safe
1. Qu'est-ce que Refit et pourquoi l'utiliser ?
Refit est une bibliothèque open source pour l'écosystème .NET qui génère automatiquement des implémentations de clients HTTP à partir d'interfaces définies par le développeur. Elle transforme une interface C# classique en un client REST complet, éliminant ainsi le besoin d'écrire manuellement du code répétitif pour les requêtes HTTP, la sérialisation/désérialisation JSON et la gestion des erreurs.
Le principal problème résolu par Refit est la lutte contre la duplication de code lors de l'interaction avec des API REST. Au lieu de créer une méthode distincte avec HttpClient pour chaque endpoint, de configurer les en-têtes, de traiter les réponses et les exceptions, le développeur déclare simplement une interface avec des méthodes annotées par des attributs Refit. La bibliothèque génère elle-même l'implémentation en utilisant HttpClientFactory (approche recommandée) ou directement HttpClient.
Refit est particulièrement utile pour le développement d'architectures microservices, l'intégration avec des API tierces (GitHub, Stripe, Telegram, etc.) et dans tout projet nécessitant une interaction type-safe avec des services HTTP. Il prend en charge toutes les méthodes HTTP principales (GET, POST, PUT, DELETE, PATCH), la gestion des en-têtes, des paramètres de requête, du corps de la requête, des formulaires multipart et des fichiers.
2. Installation
Refit est distribué via NuGet. Pour l'installer, utilisez l'une des commandes suivantes :
# Via .NET CLI
dotnet add package Refit
# Via Package Manager Console (Visual Studio)
Install-Package Refit
# Ou via le gestionnaire de packages NuGet dans votre IDE
Pour travailler avec des méthodes asynchrones et l'intégration avec ASP.NET Core, il est également recommandé d'installer le package Refit.HttpClientFactory :
dotnet add package Refit.HttpClientFactory
Si vous utilisez System.Text.Json (par défaut dans .NET Core 3.1+), aucun package supplémentaire n'est nécessaire. Pour Newtonsoft.Json, installez Refit.Newtonsoft.Json.
3. Démarrage rapide — exemple minimal fonctionnel
Créons un client simple pour récupérer des données depuis JSONPlaceholder (une API REST de test).
Étape 1 : Définissez le modèle de données :
public class Todo
{
public int Id { get; set; }
public int UserId { get; set; }
public string Title { get; set; }
public bool Completed { get; set; }
}
Étape 2 : Créez une interface avec les attributs Refit :
using Refit;
public interface ITodoApi
{
[Get("/todos/{id}")]
Task<Todo> GetTodoAsync(int id);
[Get("/todos")]
Task<List<Todo>> GetAllTodosAsync();
}
Étape 3 : Utilisez Refit pour créer le client :
using Refit;
class Program
{
static async Task Main(string[] args)
{
// Création du client directement (sans injection de dépendances)
var todoApi = RestService.For<ITodoApi>("https://jsonplaceholder.typicode.com");
// Récupération d'un seul Todo
var todo = await todoApi.GetTodoAsync(1);
Console.WriteLine($"Todo : {todo.Title}, Terminé : {todo.Completed}");
// Récupération de tous les Todos
var todos = await todoApi.GetAllTodosAsync();
Console.WriteLine($"Nombre total de todos : {todos.Count}");
}
}
Cet exemple illustre le mécanisme de base : vous décrivez une interface, et Refit génère l'implémentation qui exécute les requêtes HTTP et désérialise les réponses.
4. Méthodes/fonctions/classes principales
4.1. RestService.For<T>()
Signature : public static T For<T>(string hostUrl)
Description : Méthode statique qui crée une instance du client REST pour l'interface spécifiée. Elle prend l'URL de base du service et retourne une implémentation concrète de l'interface T. C'est le point d'entrée principal pour utiliser Refit sans injection de dépendances.
Exemple :
var api = RestService.For<IGitHubApi>("https://api.github.com");
4.2. Attributs HTTP (Get, Post, Put, Delete, Patch)
Description : Ces attributs sont appliqués aux méthodes de l'interface pour définir le type de requête HTTP et le chemin du endpoint. Ils supportent les paramètres dynamiques via des espaces réservés entre accolades.
Exemple :
public interface IUserApi
{
[Get("/users/{userId}")]
Task<User> GetUserAsync(int userId);
[Post("/users")]
Task<User> CreateUserAsync([Body] User user);
[Put("/users/{userId}")]
Task<User> UpdateUserAsync(int userId, [Body] User user);
[Delete("/users/{userId}")]
Task DeleteUserAsync(int userId);
}
4.3. Attribut [Body]
Description : Marque un paramètre comme étant le corps de la requête. Refit sérialise automatiquement ce paramètre en JSON (ou dans le format configuré) et l'envoie dans le corps de la requête HTTP.
Exemple :
[Post("/articles")]
Task<Article> CreateArticleAsync([Body] Article article);
4.4. Attribut [Header]
Description : Permet de définir des en-têtes HTTP personnalisés, soit au niveau de la méthode, soit au niveau du paramètre. Utile pour les tokens d'authentification, les clés API, etc.
Exemple :
public interface ISecureApi
{
[Get("/protected-data")]
[Header("Authorization", "Bearer")]
Task<Data> GetProtectedDataAsync();
[Get("/user-data")]
Task<UserData> GetUserDataAsync([Header("X-API-Key")] string apiKey);
}
4.5. Attribut [Query]
Description : Spécifie qu'un paramètre doit être inclus comme paramètre de requête dans l'URL. Par défaut, tous les paramètres non annotés sont traités comme des paramètres de requête, mais [Query] permet un contrôle plus explicite.
Exemple :
[Get("/search")]
Task<SearchResult> SearchAsync([Query] string query, [Query] int page = 1, [Query] int pageSize = 20);
4.6. RefitSettings
Description : Classe de configuration qui permet de personnaliser le comportement de Refit : sérialiseur personnalisé, gestion des erreurs, Content-Type, etc.
Exemple :
var settings = new RefitSettings
{
ContentSerializer = new SystemTextJsonContentSerializer(new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = true
})
};
var api = RestService.For<IMyApi>("https://api.example.com", settings);
Aussi dans la bibliothèque
Rate Limiting en Go (Golang) : bibliothèques, modèles et exemples de mise en œuvre
Psr/Log PHP : guide complet avec exemples pratiques
Travailler avec S3 et les stockages cloud en C++ : la bibliothèque aws-sdk-cpp
Client OAuth pour TypeScript : intégration de l'authentification dans les applications web
Mocha JavaScript (Node.js) : guide complet avec exemples