在Web API中生成超媒体链接

22

我很好奇其他人如何处理为他们的Web API生成超媒体链接的问题?具体来说,我正在使用ASP.NET Web API,并且在返回操作时,我犹豫于返回与超媒体相关的类型,还是返回资源本身,并在管道中稍后进行超媒体处理。 也就是说,人们是否倾向于这样做:

public Resource<Order> GetOrder(int id) { 
  return new Resource<Order>() {
      Content = new Order(),
      Links = new LinkCollection<Order>() { new AddOrderLink(), new UpdateOrderLink()}
  }

或者更像是

public Order GetOrder(int id) { return new Order(); }

那么在 HttpOperationHandler 或自定义格式化程序中添加超媒体链接?

如果采用类似于#2的方法,如何确定要生成哪些链接?为所有订单对象生成一些标准链接?使用 OrdersController 中不同操作上的属性装饰器?


附录:我已经阅读了Glenn Block在Web API中关于超媒体的帖子(http://codebetter.com/glennblock/2012/01/08/hypermedia-and-web-api-design-brain-dump-and-samples/),虽然他似乎更喜欢在操作中生成链接(类似于上面的示例1),但我觉得他在最后提到的“中间件”路线更自然。 - Jordan0Day
1
请查看Ammy在TechEd新西兰的演示:http://channel9.msdn.com/Events/TechEd/NewZealand/2013/DEV305。她的解决方案对于使用Web API的超媒体非常有前途,同时请查看这里的GitHub示例代码。 - Gomes
4个回答

25

我更喜欢第二种选择(在管道后添加超媒体链接),并在昨天博客中讨论了这个问题。

解决方案是在返回资源给客户端之前,使用消息处理程序“丰富”资源的超媒体链接。


这真的很酷,谢谢分享。我们使用扩展方法,它更像是一个饼干切割器代码,在操作方法中占据了1行代码。我喜欢你返回资源并根据上下文添加或不添加超媒体的方式。 - suing

9

您可以使用来自Github的Hyprlinkr。

我计划在我的下一个项目中使用它,因为它看起来很好而且容易实现,您可以通过NuGet软件包获取它。


3
Hyprlinkr是一个很好的解决方案,可以实际生成链接 -- 当您知道要生成哪些链接时。我的问题更多地是围绕“我如何知道我需要生成哪些链接”,而不是“我应该如何生成它们?”无论哪种方式,一旦你掌握了“如何”部分,Hyperlinkr都可以帮助解决这个问题。 - Jordan0Day

2

回答这个问题,可以参考ASP.NET MVC处理的方法,因为ASP.NET MVC可以视为Web API的文本/HTML约束版本(尽管手动内容协商除外),显然它也严重影响了Web API的设计。

基本上,我们可以使用自定义格式化程序根据路由或操作属性来变换表示方式。这是受ASP.NET MVC将视图与模型分离的启发。在ASP.NET MVC项目中,一个单一的模型可以由各种视图模板呈现。每个这些视图模板本质上都会将过渡链接(锚,表格和链接元素)“硬编码”到该特定模型的表示形式中。视图模板的选择主要是由约定(控制器和操作名称)驱动的,但也可以在操作中硬编码。

在ASP.NET MVC中的视图引擎和视图查找规则可以被认为是一个自定义的Web API格式化程序。这可以泛化,以便于每种支持的媒体类型,自定义格式化程序使用路由详细信息 - 并且可选地应用到调用的操作方法的属性 - 来定义资源状态。(在这个约定下,选择反映资源状态的操作名称是有益的。)一旦格式化程序知道了资源的状态,它就可以委托给与状态相关的格式化代码。在这个代码中,可以定义状态特定的链接。

这个状态特定格式化代码也可以委托给其他子格式化程序,就像Razor视图支持部分视图的组合一样。


1
我已经在这里添加了我的解决方案。
它使用类和属性属性与ApiController扩展方法结合使用,以填充实体中的ResourceLink对象。它还可以为任何集合属性填充链接。虽然不是最终版本,但它相当直观,并且是一个很好的开始。

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