使用C#语言的 Refit REST 库构建健壮的 API 客户端

作者:微信公众号:【架构师老卢】
9-18 16:40
143

Refit 是一个功能强大的 .NET REST 客户端库,它通过自动生成 HTTP 请求的样板代码来简化 API 客户端的构建。

借助 Refit,开发人员可以使用 C# 接口定义 API 端点,而库会处理其余部分,从而使客户端实现更简洁、更易于测试且不易出错。让我们演练如何使用 Refit 在 C# 中构建强大的 API 客户端。

为什么使用 Refit?

  • 减少样板:无需手动创建 HTTP 请求。
  • 强类型:对 API 请求和响应的结构进行编译时检查。
  • 轻松集成:与 Dependency Injection 和流行的 HTTP 客户端(如 .HttpClient
  • 可测试性:由于 API 客户端是使用接口定义的,因此可以轻松模拟它们以进行单元测试。

1. 创建新的 ASP.NET Web API 项目

dotnet new webapi -n RefitRESTLib  
cd RefitRESTLib

2. 安装 Refit

若要开始使用 Refit,请通过 .NET CLI 安装 NuGet 包:

dotnet add package Refit.HttpClientFactory --version 7.1.2

或使用 NuGet 包管理器:

NuGet Install-Package Refit.HttpClientFactory -Version 7.1.2

3. 定义 API 接口

Refit 要求您将 API 定义为具有表示 API 调用的方法的接口。以下是典型 CRUD API 的示例接口:

  • [Get]、 、 和 是将 HTTP 方法映射到相应 API 端点的 Refit 属性。[Post][Put][Delete]
  • Task<T>用于异步调用。
  • [Body]用于指定应将参数序列化到请求正文中。

4. 数据传输模型

以下是 API 接口中使用的类的示例:Post

namespace RefitRESTLib.Models  
{  
    public class Post  
    {  
        public int Id { get; set; }  
        public int UserId { get; set; }  
        public string Title { get; set; }  
        public string Body { get; set; }  
    }  
}

5. 注册 Refit Client 和 SwaggerProgram.cs

更新以配置服务和中间件。Program.cs

using Refit;
using RefitRESTLib.Services;

var builder = WebApplication.CreateBuilder(args);



builder.Services.AddControllers();
// Register Refit client
builder.Services.AddRefitClient<IJsonPlaceholderApi>()
    .ConfigureHttpClient(c => c.BaseAddress = new Uri("https://jsonplaceholder.typicode.com"));

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();



var app = builder.Build();
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

6. 实现客户端

创建控制器以处理 HTTP 请求并与 Refit 客户端交互。

创建 :Controllers/PostsController.cs

using Microsoft.AspNetCore.Mvc;
using Refit;
using RefitRESTLib.Models;
using RefitRESTLib.Services;

namespace RefitRESTLib.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class PostsController : ControllerBase
    {
        private readonly IJsonPlaceholderApi _jsonPlaceholderApi;

        public PostsController(IJsonPlaceholderApi jsonPlaceholderApi)
        {
            _jsonPlaceholderApi = jsonPlaceholderApi;
        }

        // GET: /posts
        [HttpGet]
        public async Task<ActionResult<IEnumerable<Post>>> GetPosts()
        {
            try
            {
                var posts = await _jsonPlaceholderApi.GetPostsAsync();
                return Ok(posts);
            }
            catch (ApiException ex)
            {
                return StatusCode((int)ex.StatusCode, ex.Content);
            }
        }

        // GET: /posts/{id}
        [HttpGet("{id}")]
        public async Task<ActionResult<Post>> GetPost(int id)
        {
            try
            {
                var post = await _jsonPlaceholderApi.GetPostByIdAsync(id);
                return Ok(post);
            }
            catch (ApiException ex)
            {
                return StatusCode((int)ex.StatusCode, ex.Content);
            }
        }

        // POST: /posts
        [HttpPost]
        public async Task<ActionResult<Post>> CreatePost([FromBody] Post newPost)
        {
            try
            {
                var createdPost = await _jsonPlaceholderApi.CreatePostAsync(newPost);
                return CreatedAtAction(nameof(GetPost), new { id = createdPost.Id }, createdPost);
            }
            catch (ApiException ex)
            {
                return StatusCode((int)ex.StatusCode, ex.Content);
            }
        }

        // PUT: /posts/{id}
        [HttpPut("{id}")]
        public async Task<ActionResult<Post>> UpdatePost(int id, [FromBody] Post updatedPost)
        {
            try
            {
                var post = await _jsonPlaceholderApi.UpdatePostAsync(id, updatedPost);
                return Ok(post);
            }
            catch (ApiException ex)
            {
                return StatusCode((int)ex.StatusCode, ex.Content);
            }
        }

        // DELETE: /posts/{id}
        [HttpDelete("{id}")]
        public async Task<IActionResult> DeletePost(int id)
        {
            try
            {
                await _jsonPlaceholderApi.DeletePostAsync(id);
                return NoContent();
            }
            catch (ApiException ex)
            {
                return StatusCode((int)ex.StatusCode, ex.Content);
            }
        }
    }
}

7. 运行应用程序

dotnet run

请求正文示例

{  
  "userId": 1,  
  "title": "Refit Post",  
  "body": "This post was created using Refit in an ASP.NET Web API."  
}

Refit 通过减少样板代码、提供强类型化和简化测试,简化了 .NET 中的 API 客户端开发。它可以轻松集成到 ASP.NET Core 中,并且可以灵活地处理 API 端点,因此它是在 C# 中构建强大的 API 客户端的绝佳工具。

源代码获取:公众号回复消息【code:89705

相关代码下载地址
重要提示!:取消关注公众号后将无法再启用回复功能,不支持解封!
第一步:微信扫码关键公众号“架构师老卢”
第二步:在公众号聊天框发送code:89705,如:code:89705 获取下载地址
第三步:恭喜你,快去下载你想要的资源吧
相关留言评论
昵称:
邮箱:
阅读排行