你如何表示RESTful资源的“瘦”和“胖”版本?

时间:2014-05-13 02:28:01

标签: rest hateoas hypermedia

您如何为可以具有两种不同表示的资源建模。例如,一个表示可以是“薄的”,其大多数相关资源可通过链接访问。另一种表示可能是“胖”,其中嵌入了大部分相关资源。这个想法是,一些客户不介意不必多次调用浏览链接资源,但其他客户想要一次性获取数据。

考虑与导演,演员等相关联的电影资源。也许它的精简版仅具有电影标题,并且为获取导演,演员列表等的数据,必须另外通过嵌入式链接向他们请求。也许它的胖版包含嵌套在里面的所有电影,包括导演的数据,各种演员的数据等。

如何对此进行建模?

我看到了几个选项:

  1. 这两个表示实际上是两个不同的资源,需要不同的URI
  2. 这两个表示实际上是相同的资源,您可以通过自定义媒体类型在两个表示之间进行选择,例如application/vnd.movie.thin+jsonapplication/vnd.movie.fat+json
  3. 这两个表示实际上是相同的资源,选择不同的表示应该使用查询参数(例如/movies/1?view=thin)。
  4. 别的......
  5. 您认为这种API的正确方法是什么?

3 个答案:

答案 0 :(得分:4)

您可以将prefer header与return-minimal参数一起使用。

答案 1 :(得分:2)

我更喜欢使用Content-Type。您也可以使用参数:

application/vnd.myapp; profile=light

答案 2 :(得分:1)

Fielding dissertation about REST告诉您资源接口,您必须将IRI绑定到资源,这些资源是实体集。 (这与SOAP不同,因为在那里你通常将IRI绑定到操作。)

根据Darrel Millerthe path is for describing hierarchical data and the query string is for describing non-hierarchical data in IRIs,但我们一起使用路径和查询来识别API中的资源。

基于这些,你有两种方法:

  • 您可以说,具有较少属性的同一实体可以映射到具有自己的IRI的新资源。在这种情况下,/movies/1?view=thin/movies/1/view:thin也可以 优点:

    • 根据 RDF a 属性具有rdf:type rdf:Propertyrdfs:Resource,并且REST与语义Web和链接数据有关联。
    • 通常的做法是为单个属性创建IRI,例如/movies/1/title,因此如果我们可以通过单个属性执行此操作,那么我们也可以通过一组属性来执行此操作。 / LI>
    • 它类似于我们已经用于收集entites的map reduce/movies/recent等......唯一的区别是,通过实体集合我们减少列表或有序集,以及通过我们减少地图的属性集合。将两者组合使用会更加有趣,例如:/movies/recent/title,它可以返回最近电影的标题。

    缺点:

    • 通过RDF,所有内容都有rdf:type rdfs:Resource,并且REST可能不会遵循Web文档的相同原则。
    • 我还没有发现任何关于单个属性或属性集合的内容可以或不能被视为论文中的资源,但是我可能会意外地跳过该部分文本(相当干燥的东西)......
  • 您可以说具有较少属性的同一实体只是同一资源的不同表示,因此它不应具有不同的IRI。在这种情况下,您必须将有关首选视图的数据放入请求中的其他位置。由于GET请求没有正文,并且HTTP方法不存储这类内容,因此唯一可以放置它的是HTTP头。通过长期用户特定设置,您可以将其存储在服务器上,或存储在客户端维护的cookie中。通过短期设置,您可以在许多标题中发送它。通过content-type标题,您可以定义自己的MIME类型,这是不推荐的,因为我们不喜欢只有一个应用程序可能使用数百种自定义MIME类型。通过content-type标头,您可以将profile添加到您建议的Doug Moscrop的MIME类型中。通过prefer header,您可以将return-minimal设置用作Darrel Miller建议。通过range headers你可以在理论上做同样的事情,但我只通过分页来满足范围标题 优点:

    • 这当然是一种RESTful方法。

    缺点:

    • 现有的HTTP框架并不总是支持提取这些标头参数,因此您必须编写自己的短代码才能执行此操作。
    • 我找不到任何关于这些标头如何影响客户端和服务器端缓存机制的信息,因此某些浏览器可能不支持某些标头,而服务器则需要编写自己的缓存实现,或找到一个框架支持您要使用的标题。

注意:我个人更喜欢使用第一种方法,但这只是一种意见。

根据Darrel Miller,IRI的命名并不真正依赖于REST。

您必须确保单个IRI始终指向相同的资源,而这一切都是。 IRI的结构不计入客户端,因为如果您不希望它因IRI命名的任何更改而中断,则客户端必须满足HATEOAS约束。这意味着,服务器始终构建IRI,客户端遵循它在超媒体响应中获得的这些IRI。这就像使用Web浏览器关注链接一样,因此浏览网页...通过REST,您可以为超媒体添加一些语义,向您的客户解释它刚刚获得的内容。这可以是一些RDF词汇表,例如schema.org,微数据,iana链接关系等等(甚至是你自己的应用程序特定词汇)...
因此,使用漂亮的IRI并不是REST所关心的问题,只需在服务器端配置路由即可。您必须确保REST IRI,您有资源 - IRI映射而不是操作 - IRI映射,并且您不使用IRI来维护客户端状态,例如存储用户ID,凭据等。 ..