3

我们使用aspnet-api-version作为我们 API 的版本。虽然该库允许在一个控制器上交错实现多个版本。

[ApiVersion( "2.0" )]
[ApiVersion( "3.0" )]
[RoutePrefix( "api/helloworld" )]
public class HelloWorld2Controller : ApiController
{
    [Route]
    public string Get() => "Hello world v2.0!";

    [Route, MapToApiVersion( "3.0" )]
    public string GetV3() => "Hello world v3.0!";
}

我们希望将特定于版本的控制器分开。

我看到的版本特定控制器和使用这个库的问题是,我们必须再次重新实现所有 API 方法,无论它们是否已更改。考虑这个例子

[RoutePrefix("api/v{version:apiVersion}/values")]
[ApiVersion( "1.0" )]
public class ValuesController : ApiController
{
    // GET api/values
    [Route]
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }

    // GET api/values/5
    [Route("{id:int}")]
    [Route, MapToApiVersion( "1.0" )]
    public string Get(int id)
    {
        return id.ToString();
    }
}


[RoutePrefix("api/v{version:apiVersion}/values")]
[ApiVersion( "2.0" )]
public class ValuesControllerV2 : ValuesController
{
    // GET api/values/5
    [Route("{id:int}")]
    [Route, MapToApiVersion( "2.0" )]
    public string Get(int id)
    {
        return id.ToString();
    }
}

V1 api(使用ValuesController)定义了两个 API 函数GetGet(ById). 但是 v2 apiValuesControllerV2在覆盖Get(ById)时,它必须重新实现或调用基本方法Get以使GetAPI 在 V2 上可用。

有没有更好的策略,我们不必为所有在 API 升级时保持不变的函数重新实现或编写传递。

4

1 回答 1

3

首先,我建议评估您的版本控制策略。大多数服务作者(和/或公司)定义了类似N-2的策略。这将帮助您确定这个问题有多大,或者它是否甚至是一个问题。

可以使用继承,但有龙。在 Web API 中,您需要做一些额外的事情才能使其正常工作。内置实现不支持继承的 RoutePrefixAttributeRouteAttribute。您还应该考虑不能取消继承操作。如果您取消 API,这会使策略变得非常混乱。并非所有版本控制方案都向后兼容或前滚。

我强烈建议您将业务逻辑保留在服务之外。通用基类非操作方法或扩展方法可以帮助减少重复代码。如果每个操作的实施规模很小,并且您有既定的版本控制策略,那么重复就不是问题。

任何一种方法或两者的组合都应该提供足够的灵活性。

于 2018-03-26T01:27:57.563 回答