Skip to content
Go back

Refit:让 .NET REST API 调用更简单高效的利器

Published:  at  12:00 AM

Refit:让 .NET REST API 调用更简单高效的利器

在 .NET 开发中,调用 REST API 是常见需求,通常开发者会直接使用功能强大的 HttpClient。它虽然灵活但涉及大量样板代码,如手动拼接 URL、序列化请求体、解析响应等。

Refit 提供了更优雅且低成本的解决方案,它让你通过定义接口并使用特性(Attributes)声明 HTTP 请求而自动生成客户端代码,极大简化了调用流程。

什么是 Refit?

Refit 是基于 System.Net.Http.HttpClient 的一个 REST API 客户端库。 它自动承担 JSON 序列化与反序列化任务,你只关心接口定义和业务逻辑。

传统调用 REST API 需要你编写具体实现、构造请求、解析响应,而 Refit 仅需声明接口定义,自动生成实现,显著减少重复代码并提升开发效率。它同时兼容同步调用、异步调用、以及支持 CancellationToken。

此设计提高了代码的可读性和可测试性,方便替换 Mock,且完美结合依赖注入与 .NET HttpClientFactory 机制,利于构建现代化的网络调用架构。

适用场景包括微服务调用、第三方 API 整合、跨平台客户端与服务端接口封装。特别适合团队中注重开发效率和代码质量的项目。

此外,Refit 也支持多种序列化库插件(如 System.Text.Json、Newtonsoft.Json),灵活满足不同项目需求。

GitHub API 示例

以 GitHub 公共 API 为例,下面展示如何快速构建一个获取用户信息的客户端。

步骤 1:安装 NuGet 包

dotnet add package Refit.HttpClientFactory

步骤 2:定义 API 接口

创建 IGitHubApi.cs

using Refit;
using System.Threading.Tasks;

public interface IGitHubApi
{
    [Get("/users/{username}")]
    Task<GitHubUser> GetUserAsync(string username);
}

这里 [Get] 表明这是一个 HTTP GET 请求,{username} 会被动态替换为方法参数。

步骤 3:定义数据模型

创建 GitHubUser.cs

public class GitHubUser
{
    public string Login { get; set; }
    public string Name { get; set; }
    public string Company { get; set; }
    public int Followers { get; set; }
    public int Following { get; set; }
    public string AvatarUrl { get; set; }
}

该类映射了 GitHub API 返回的 JSON 字段。

步骤 4:配置依赖注入

Program.cs 或者 .NET 8 Startup 配置中集成 Refit:

builder.Services.AddRefitClient<IGitHubApi>()
    .ConfigureHttpClient((sp, client) =>
    {
        var settings = sp.GetRequiredService<IOptions<GitHubSettings>>().Value;
        client.BaseAddress = new Uri(settings.BaseAddress);
        client.DefaultRequestHeaders.Add("Authorization", settings.AccessToken);
        client.DefaultRequestHeaders.Add("User-Agent", settings.UserAgent);
    });

这里将 IGitHubApi 注册为 Typed Client,由 Refit 自动实现接口。结合依赖注入后,调用接口代理简洁方便:

var user = await gitHubService.GetUserAsync("StefanTheCode");

传统 HttpClient 调用示例对比

使用常规 HttpClient,你需要手动管理 HTTP 请求和响应,写大量样板代码:

public class GitHubApiClient : IGitHubApi
{
    private readonly HttpClient _httpClient;

    public GitHubApiClient(HttpClient httpClient)
    {
        _httpClient = httpClient;
        _httpClient.BaseAddress = new Uri("https://api.github.com");
    }

    public async Task<GitHubUser> GetUserAsync(string username)
    {
        var response = await _httpClient.GetAsync($"/users/{username}");
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadFromJsonAsync<GitHubUser>();
    }
}

相比之下,使用 Refit 只需声明接口即可完成相同的功能,极大减少了样板代码,维护成本更低。

在 .NET 8 中的优势

在 .NET 8 中,Refit 的优势更为突出,结合新语言特性与性能提升,带来:

集成示例

builder.Services.AddRefitClient<IGitHubApi>()
    .ConfigureHttpClient(client =>
    {
        client.BaseAddress = new Uri("https://api.github.com");
        client.DefaultRequestHeaders.Add("User-Agent", "MyApp");
    });

通过上述方式,借助 .NET 8 框架,Refit 能带来更流畅与易维护的 REST API 调用体验。

高级特性及示例

Refit 的高级功能使其适合复杂的 REST API 调用场景,下面配合示例介绍常用特性:

从 OpenAPI JSON 生成接口

对于大型 API 或频繁更新的服务,手动维护接口很费力。可以通过 OpenAPI JSON 规范自动生成 Refit 接口代码。

使用 NSwag 或 OpenAPI Generator

示例

假设有 OpenAPI JSON 描述的 GitHub API,可以通过 NSwag CLI 生成客户端:

nswag openapi2csclient /input:https://api.github.com/swagger.json /classname:GitHubApiClient /namespace:YourNamespace /generateDtoTypes:true /useRefit:true /output:GitHubApiClient.cs

生成接口用法

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

var api = sp.GetRequiredService<IGitHubApi>();
var user = await api.GetUserAsync("username");

注意事项

通过这种方式,极大降低手工维护接口代码成本,提升开发效率和准确性。

总结

以上示例展示了 Refit 的高级灵活使用方式,帮助你在实际项目中更高效地管理复杂 API 调用需求。



Next Post
五大常见REST API设计错误及其实战改进方案