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

11

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

从调查来看,似乎有两种方法。一种是创建API区域和返回JSON / XML控制器。另一种是使用操作过滤器和单个前端控制器集,根据请求标头返回JSON / XML / HTML。

我想采用后一种方法,但我想知道如何在这种情况下对API进行版本控制?

如果您选择第一种方法,可以轻松地创建v1 / v2控制器,但如果您选择后一种方法,该如何进行版本控制?

2个回答

12

版本控制本身就是个相当复杂的问题。以下是我之前考虑过的方法:

  1. URL。在此情况下,https://api.example.com/v1/projects 被认为是与 http://api.example.com/v2/projects 不同的资源,即使它们实际上并非如此。像 Basecamp 这样做。遵循这种方法,需要始终支持旧的 API。
  2. Headers。URL 保持不变,但客户端通过每个请求传递一个额外的 HTTP header,比如 X-MYAPI-VERSION 的值来标识所使用的 API 版本。 Google Documents List API 就是这样做的。这种方法的一个潜在问题在于,HTTP headers 可能会被客户端和服务器之间的中间件删除。
  3. Parameters。为了解决选项 2 中的问题,可以将要使用的 API 版本作为参数传递(例如,https://api.example.com/projects?v=3)。
  4. Media types。在这种情况下,URL 保持不变,但用户需要使用 accept 和 content type headers 来指定资源的表示形式。例如,"project" 可以使用 "application/vnd.mycompany.resource[-version][+format]" 表示,其中 v1 json 的表现形式为 "application/vnd.mycompany.project-v1+json",v1 xml 的表现形式为 "application/vnd.mycompany.project-v1+xml"。当需要新版本的项目时,mime 类型可能如下所示:"application/vnd.mycompany.project-v2+xml"。像 Github 这样支持它。
  • 负载的一部分。在这种情况下,请求的负载包含要使用的版本号。例如,当传递XML时,可以查看命名空间以确定正在使用哪个版本的API。对于JSON,您可以使用"$version"或"_version"属性指定版本。
  • 客户端密钥。当应用程序注册时,它会指定要使用的API版本。验证客户端时,确保模拟它想要使用的版本。
  • 无显式版本控制。始终有选择不对API进行版本控制,并尝试通过使所有字段可选并在缺失时适当处理它们来透明地处理更改。有可能您将为使未来版本的API与今天开发的版本兼容而执行此操作。
  • 许多人推荐第4种选项,虽然不总是切实可行。大多数这些选项需要额外的工作才能与ASP.NET MVC配合使用。


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

    3
    你可以选择以下两种方式之一——将API包含在路由中(而不是http://app.lication/category/1,你可以使用类似于http://app.lication/api/v1/category/1的东西),或者你可以包含一个自定义HTTP头。无论哪种方式都可以让你区分正在调用的版本。

    关于选项1 - 你能详细说明一下吗?当执行OP想要的操作 - 返回JSON/XML/HTML的单个控制器集时,如何实现并不明显。因为他可能不希望在他的HTML URL中出现“/v1”。 - Gabe Moothart
    @GabeMoothart - 你可以使用ASP.Net Routing(http://msdn.microsoft.com/en-us/library/cc668201.aspx)来定义/提取URL参数。将API作为路径的一部分并不意味着您需要为每个API拥有一个控制器(如果API差异很大,则也不排除这种可能性)。 - 48klocs

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接