改装:版本化路线

Refit: versioned routes

我们在您的 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);

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

您可以通过不同的方式实现此目的: 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; } }
      .....
}

3) 在 ICategoryApi 创建期间为 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>()