问题 ASP.NET MVC应用程序的REST API版本控制


我正在寻找在ASP.NET MVC 3中开发应用程序,并希望同时提供一个公共API。

从四处看看,似乎有两种方法可以实现。创建一个API区域并拥有返回json / xml的控制器。或者使用动作过滤器和单个前端控制器集,并根据请求标头返回json / xml / html。

我想稍后再做,但是我想知道如果你走这条路线你怎么能去版本化你的api?

如果你走第一条路线,你可以很容易地创建一个v1 / v2控制器,但是如果你这样做,你怎么能对它进行版本化?


12583
2018-02-08 16:59


起源



答案:


版本控制是一个相当复杂的问题。以下是我以前看过的方法:

  1. 网址。在这种情况下 https://api.example.com/v1/projects 假设是一个不同的资源 http://api.example.com/v2/projects,即使事实并非如此。 大本营 好像这样做。遵循这种方法,假设您始终必须支持旧的API。
  2. 。 URL保持不变,但是,客户端传递额外的HTTP标头,例如X-MYAPI-VERSION,每个请求都带有一个标识要使用的API版本的值。该 Google文档列表API 做这个。这种方法的一个潜在问题是HTTP头可能被客户端和服务器之间的中介剥离。
  3. 参数。要绕过选项2的问题,您可以传递API版本以用作参数(例如 https://api.example.com/projects?v=3)。
  4. 媒体类型。这里您的URL保持不变,但是,用户需要使用accept和content类型标头指定资源的表示。例如,可以使用“application / vnd.mycompany.resource [-version] [+ format]”呈现“项目”,为v1 json提供“application / vnd.mycompany.project-v1 + json”的表示或“ application / vnd.mycompany.project-v1 + xml“for v1 xml。当您需要新版本的项目时,mime类型可能如下所示“application / vnd.mycompany.project-v2 + xml”。 Github上 似乎支持这一点。
  5. 部分有效载荷。在这种情况下,请求的有效负载包含要使用的版本号。例如,传递XML时,您可以查看命名空间以确定正在使用的API版本。对于JSON,您可以使用“$ version”或“_version”属性来指定版本。
  6. 客户密钥。注册应用程序时,它指定要使用的API版本。验证客户端时,确保模拟其要使用的版本。
  7. 没有明确的版本控制 始终可以选择不对API进行版本控制,并尝试通过使所有字段都可选而透明地处理更改,并在缺少时适当地处理它们。您无论如何都可能会这样做,以使您的API的未来版本与您当前开发的版本兼容。

许多人推荐选项4,虽然它并不总是实用。大多数这些选项需要额外的工作才能使用ASP.NET MVC。


11
2018-06-09 03:01



如果您对方法#1(我的偏好)感兴趣,那么请查看这个NuGet包以及GitHub上的相应代码/示例: nuget.org/packages/VersionedRestApi/1.0.0.2 - jakejgordon
对于方法#2(我的偏好),User-Agent将是此方法的正确标题(w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43)。 “该字段可以包含多个产品令牌(第3.8节)和标识代理的注释以及构成用户代理重要部分的任何子产品”示例将是:User-Agent:YOUR_API_ID / 2.0 - Fabian Köbel
我不同意使用User-Agent来版API。规范指的是客户端产品。例如,连接到HTTP服务器的浏览器。当客户端的应用程序开发人员使用User-Agent指定其客户端时,它有更多的好处,因此我们可以从客户端角度跟踪API使用情况。当AppX / 1.1在某些MyAPI v1.1调用失败时非常有用,但AppX / 1.2没有。你将失去那种跟踪。 - bloudraak


答案:


版本控制是一个相当复杂的问题。以下是我以前看过的方法:

  1. 网址。在这种情况下 https://api.example.com/v1/projects 假设是一个不同的资源 http://api.example.com/v2/projects,即使事实并非如此。 大本营 好像这样做。遵循这种方法,假设您始终必须支持旧的API。
  2. 。 URL保持不变,但是,客户端传递额外的HTTP标头,例如X-MYAPI-VERSION,每个请求都带有一个标识要使用的API版本的值。该 Google文档列表API 做这个。这种方法的一个潜在问题是HTTP头可能被客户端和服务器之间的中介剥离。
  3. 参数。要绕过选项2的问题,您可以传递API版本以用作参数(例如 https://api.example.com/projects?v=3)。
  4. 媒体类型。这里您的URL保持不变,但是,用户需要使用accept和content类型标头指定资源的表示。例如,可以使用“application / vnd.mycompany.resource [-version] [+ format]”呈现“项目”,为v1 json提供“application / vnd.mycompany.project-v1 + json”的表示或“ application / vnd.mycompany.project-v1 + xml“for v1 xml。当您需要新版本的项目时,mime类型可能如下所示“application / vnd.mycompany.project-v2 + xml”。 Github上 似乎支持这一点。
  5. 部分有效载荷。在这种情况下,请求的有效负载包含要使用的版本号。例如,传递XML时,您可以查看命名空间以确定正在使用的API版本。对于JSON,您可以使用“$ version”或“_version”属性来指定版本。
  6. 客户密钥。注册应用程序时,它指定要使用的API版本。验证客户端时,确保模拟其要使用的版本。
  7. 没有明确的版本控制 始终可以选择不对API进行版本控制,并尝试通过使所有字段都可选而透明地处理更改,并在缺少时适当地处理它们。您无论如何都可能会这样做,以使您的API的未来版本与您当前开发的版本兼容。

许多人推荐选项4,虽然它并不总是实用。大多数这些选项需要额外的工作才能使用ASP.NET MVC。


11
2018-06-09 03:01



如果您对方法#1(我的偏好)感兴趣,那么请查看这个NuGet包以及GitHub上的相应代码/示例: nuget.org/packages/VersionedRestApi/1.0.0.2 - jakejgordon
对于方法#2(我的偏好),User-Agent将是此方法的正确标题(w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43)。 “该字段可以包含多个产品令牌(第3.8节)和标识代理的注释以及构成用户代理重要部分的任何子产品”示例将是:User-Agent:YOUR_API_ID / 2.0 - Fabian Köbel
我不同意使用User-Agent来版API。规范指的是客户端产品。例如,连接到HTTP服务器的浏览器。当客户端的应用程序开发人员使用User-Agent指定其客户端时,它有更多的好处,因此我们可以从客户端角度跟踪API使用情况。当AppX / 1.1在某些MyAPI v1.1调用失败时非常有用,但AppX / 1.2没有。你将失去那种跟踪。 - bloudraak


您可以选择两条路线中的一条 - 您可以在路线中包含API(而不是 http://app.lication/category/1 你会有类似的东西 http://app.lication/api/v1/category/1或者你可以包括一个 自定义HTTP标头

要么允许您区分被调用的版本。


3
2018-02-08 17:05



关于选项1 - 你能详细说明吗?在做OP想要做的事情时,如何做到这一点并不明显 - 一组控制器根据请求头返回json / xml / html。因为大概是他不想要的 /v1 在他的HTML网址中。 - Gabe Moothart
@GabeMoothart - 您将使用ASP.Net路由(msdn.microsoft.com/en-us/library/cc668201.aspx)定义/提取URL参数。使API成为路径的一部分并不意味着您需要为每个API配备一个控制器(如果API完全不同,也不会排除它)。 - 48klocs