ASP.NET API版本控制

6ss1mwsb  于 2022-11-19  发布在  .NET
关注(0)|答案(2)|浏览(192)

我是ASP.NET的新手,但我希望为我即将开始的新API实现一些版本控制。
我甚至不确定我所寻找的是可能的,但我在一个非常干净的版本方法使用头部变量后。
理想情况下,我希望能够在代码结构中有一个版本文件夹,并且在不同的文件夹中包含不同的API版本。每个版本文件夹都将包含核心API代码的完整副本,这样我就知道不会有任何冲突等。我知道这会使代码膨胀,但保持代码非常干净是值得的,并且只有超过2-3个API版本处于活动状态。
我在互联网上找到了许多头文件示例,但它们都要求类位于不同的命名空间中,如果我要做代码的完整副本,那么每次复制时都要重命名所有类是不现实的。
我正在尝试做的事情是可能的吗?或者在处理多个类时有没有更干净的解决方案?

oprakyz7

oprakyz71#

有四种基本的方法来版本化RESTful方式-

  1. URI路径此方法采用以下形式:
  1. URI参数此方法采用以下形式:

1.内容协商这是在HTTP报头中完成的。

  • 内容类型:应用程序/vnd. taskManager应用程序

1.请求标头这也在HTTP标头中完成。

  • x-taskManagerApp-版本:2个 *

我个人喜欢第一种方法。你可以读Mike Wasson's ASP.NET Web API: Using Namespaces to Version Web APIs
很多人修改了Mike Wasson的原始源代码。我喜欢ASP.NET Web API 2 book by Jamie Kurtz, Brian Wortman中使用的那个。
因为它有太多的移动部分,我创建了a sample project at GitHub

config.Routes.MapHttpRoute(
   name: "DefaultApi",
   routeTemplate: "api/{version}/{controller}",
   defaults: new { version = "v2" }
);

config.Routes.MapHttpRoute(
   name: "DefaultApiWithId",
   routeTemplate: "api/{version}/{controller}/{id}",
   defaults: new { id = RouteParameter.Optional }
);

然后,添加ApiVersionConstraint

public class ApiVersionConstraint : IHttpRouteConstraint
{
    public ApiVersionConstraint(string allowedVersion)
    {
        AllowedVersion = allowedVersion.ToLowerInvariant();
    }

    public string AllowedVersion { get; private set; }

    public bool Match(HttpRequestMessage request, IHttpRoute route, string parameterName,
        IDictionary<string, object> values, HttpRouteDirection routeDirection)
    {
        object value;
        if (values.TryGetValue(parameterName, out value) && value != null)
        {
            return AllowedVersion.Equals(value.ToString().ToLowerInvariant());
        }
        return false;
    }
}

用法

您只需将RoutePrefix放在控制器上,就完成了。

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

    // GET api/v1/values/5
    [Route("{id}")]
    public string Get(int id)
    {
        return "v1-value-" + id;
    }
}
yqkkidmi

yqkkidmi2#

这是一个有点晚的答案,但是对于仍然希望将版本控制应用于ASP.NET Web API堆栈的任何人来说,ASP.NET API Versioning已经成为实现它的一种非常常用的方法。Basic Sample将带您完成开始使用的所有必要步骤。
API版本控制支持查询字符串、头、媒体类型和URL段。如果支持多个方法,您可以将方法组合在一起,甚至可以创建自己的方法来提取API版本。默认的版本控制方法是通过查询字符串。尽管它很受欢迎,而且@Win也给出了建议,我推荐通过URL分段进行版本控制。这是最不符合RESTful的方法,因为它违反了 Uniform Interface 约束,并且有过多的有问题的边缘情况。
从添加ASP.NET Web API Versioning NuGet包开始,你想如何版本化以及如何组织代码是非常主观的,但这里有一个非常简单的设置:

namespace Example
{
   public class WebApiConfig
   {
       public static Configure(HttpConfiguration config)
       {
           // TODO: this is the minimum, but there are many options that can be configured
           config.AddApiVersioning();

           // TODO: remaining configuration
       }
   }

   // this is one of many possible ways you might organize controllers
   namespace Controllers
   {
       namespace V1
       {
           [ApiVersion("1.0")]
           [RoutePrefix("values")]
           public class ValuesController : ApiController
           {
               // GET /values?api-version=1.0
               [Route]
               public IHttpActionResult Get(ApiVersion version) =>
                   Ok(new []{$"v{version}-Value1", $"v{version}-Value2"});

               // GET /values/{id}?api-version=1.0
               [Route("{id}")]
               public IHttpActionResult Get(int id, ApiVersion version) =>
                   Ok($"v{version}-{id}")
           }
       }

       namespace V2
       {
           [ApiVersion("2.0")]
           [RoutePrefix("values")]
           public class ValuesController : ApiController
           {
               // GET /values?api-version=2.0
               [Route]
               public IHttpActionResult Get(ApiVersion version) =>
                   Ok(new []{$"v{version}-Value1", $"v{version}-Value2"});

               // GET /values/{id}?api-version=2.0
               [Route("{id}")]
               public IHttpActionResult Get(int id, ApiVersion version) =>
                   Ok($"v{version}-{id}")
           }
       }
   }
}

相关问题