首页 > 解决方案 > 改装:版本化路线

问题描述

我们在您的一个 API 上使用 Refit 来为该 API 创建和共享客户端包。

ICategoryApi.cs

[Post("/category")]
Task CreateCategoryAsync([Body] CategoryCommandDto createCategoryCommandDto);

并且使用控制器一切正常

CategoryController.cs

[ApiController]
[Route("[controller]")]
public class CategoriesController : ControllerBase
{
    [HttpPost]
    [ProducesResponseType((int)HttpStatusCode.Created)]
    [ProducesResponseType((int)HttpStatusCode.BadRequest)]
    public async Task<IActionResult> CreateCategory([FromBody] CategoryCommandDto createCategoryCommandDto)
    {
          //some code
    }
}

问题是现在我们已经添加了 api 版本控制,并且我们选择了按路由进行版本控制。

所以现在端点/category看起来像,我们将很快/v1/category创建一个。/v2/category

有没有办法配置refit(通过属性或类似的)它来理解我的版本化路由?

我想避免为每个新版本的 API 编写一个新客户端,并在端点路由中包含该版本,例如

ICategoryApiV1.cs

[Post("/v1/category")]
Task CreateCategoryAsync([Body] CategoryCommandDto createCategoryCommandDto);

想象一下,客户端更大,有很多方法,而不仅仅是一个。此外,并非所有方法都可能在版本之间发生变化。

标签: c#asp.net-core.net-coreasp.net-core-webapirefit

解决方案


您可以通过不同的方式实现这一点:1)像方法中的参数一样使用;

ICategoryApiV1.cs

[Post("/{v}/category")]
Task CreateCategoryAsync([Body] CategoryCommandDto createCategoryCommandDto, [AliasAs("v")]int version = 1);

2)在里面定义一个属性CategoryCommandDto

public class CategoryCommandDto
{
    // Properties can be read-only and [AliasAs] isn't required
    public int v { get { return 1; } }
      .....
}

ICategoryApi3)在创建时为httpClient定义一个baseUrl

services.AddRefitClient<ICategoryApi>()
    .ConfigureHttpClient(c => c.BaseAddress = new Uri($"https://api.example.com/{version}"));

4) 或者,如果您需要一些高级计算,您可以添加自定义 HttpHandler 并在您的客户端中进行配置。

services.AddRefitClient<ICategoryApi>(settings)
        .ConfigureHttpClient(c => c.BaseAddress = new Uri("https://api.example.com"));
        .AddHttpMessageHandler<VersionHandler>()

推荐阅读