使用WCF或ASP.Net Web Api实现RESTful API版本控制

6
假设我已经阅读了大量有关版本控制RESTful API的信息,并决定不通过URI进行版本控制,而是使用媒体类型(在请求接受标头中的格式和模式):
那么,如何实现WCF服务或Web API服务来处理在URI中定义请求资源,在接受标头中定义格式(例如application/json)和模式/版本(例如player-v2)的请求?
WCF允许我基于URI路由,但不能基于标头路由。因此,我无法正确路由。
Web API允许我定义自定义mediatypeformatters,路由请求的格式,但不能定义模式(例如返回类型PlayerV1或PlayerV2)。
我希望实现一个服务(使用WCF或Web API),为此请求(伪代码):
api.myservice.com/players/123 Accept format=application/json; schema=player-v1

返回一个以json格式表示的PlayerV1实体。
对于此请求:
api.myservice.com/players/123 Accept format=application/json; schema=player-v2

以json格式返回PlayerV2实体。

如何实现此功能?

编辑:为了澄清我为什么想使用内容协商来处理版本,请参见这里:REST API设计:将“类型”放入“内容类型”中

1个回答

2
你所带来的东西在我看来不是版本控制,而更多地是内容协商。接受标头表达了客户端对资源格式的期望。服务器应该满足这些期望或返回406状态码。因此,如果我们需要更多的契约概念(尽管Web API不像RPC那样定义一个契约),那么使用“资源”更为可靠。
版本控制的最佳实践尚未完全讨论,但大多数REST爱好者认为在URL中使用版本号是正确的方式(例如http://server/api/1.0.3/...)。这对我来说也更有意义,因为在你的方法中使用内容协商,服务器必须保持向后兼容性,我只能想象服务器上的代码会变得越来越复杂。使用URL方法,您可以进行干净的断裂:旧客户端可以继续使用以前的API,而新客户端可以享受新API的好处。

更新

现在问题已经变成了“在RESTful AP中实现内容协商”。

类型1:控制器无关

基本上,如果内容协商仅涉及资源的格式,则实现或使用正确的媒体类型格式化程序就足够了。例如,如果内容协商涉及返回JSON或XML,则可以这样做。在这些情况下,控制器对内容协商视而不见

类型2:控制器感知

控制器需要意识到请求的协商。在这种情况下,需要从请求中提取参数并作为参数传递。例如,让我们想象一下控制器上的这个操作:

public Player Get(string schemaVersion)
{
    ...
}

在这种情况下,我会使用经典的MVC样式值提供程序(参见Brad Wilson有关ValueProviders的文章 - 这是关于MVC的,但Web API的值提供程序看起来类似):
public Player Get([ValueProvider(typeof(RequestHeadersSchemaValueProviderFactory))]string schemaVersion)
{
    ...
}

2
让我们不要开始关于哪种方式更好(URI中的版本或非URI中的版本)的讨论,因为这不是重点。我可以重新表述问题:“在RESTful API中实现内容协商..”,实现挑战仍然是相同的,不是吗? - codeclash
值提供程序将使我能够访问所请求的方案,但在任何情况下,您示例中的返回类型将是Player,而实际上我需要返回Player或PlayerV2,具体取决于所请求的方案。我有什么遗漏吗? - codeclash
在这种情况下,将响应定义为HttpResponseMessage,然后将内容设置为正确的对象内容即可。 - Aliostad
我对你的回答并不是很满意(尽管其中一些帮助了我),但是把责任归咎于我:可能一开始并不清楚我在寻找什么,您可能是对的:一旦确定了我的用例清晰明确,我应该重新表述我的问题,并从一开始就给出具体的例子。谢谢你的建议,我会接受你的答案,你提供了帮助和建议。 - codeclash
1
@AlexAvrutin 版本控制通常涉及在URL中包含版本号:/api/1.2.3/cars/123 - Aliostad
显示剩余5条评论

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