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

Sin*_*hot 5 rest hateoas hypermedia

您将如何对可以具有两种不同表示形式的资源进行建模。例如,一个表示可能很“瘦”,其大部分相关资源都可以通过链接访问。另一种表示形式可能是“胖”,其中嵌入了大多数相关资源。这个想法是,有些客户不介意打很多电话来浏览链接的资源,而另一些客户则想一次获取所有数据。

考虑与导演,演员等相关的电影资源。也许它的精简版仅具有电影标题,并且要获取导演,演员列表等的数据,必须通过发出其他请求。嵌入到它们的链接。也许胖版本包含了嵌套在里面的所有电影,包括导演的数据,各个演员的数据等。

一个应该如何建模?

我看到一些选择:

  1. 这两种表示形式实际上是两种不同的资源,并且需要不同的URI。
  2. 这两种表示形式实际上是相同的资源,您可以通过自定义媒体类型在两种表示形式之间进行选择,例如application/vnd.movie.thin+jsonapplication/vnd.movie.fat+json
  3. 这两种表示实际上是相同的资源,选择不同的表示应使用查询参数(例如 /movies/1?view=thin)。
  4. 还有别的...

您如何看待这种API的正确方法?

Dar*_*ler 5

您可以将preferred标头与return-minimal参数一起使用。


inf*_*rno 1

关于 REST 的 Fielding 论文告诉您有关资源接口的信息,您必须将 IRI 绑定到资源(实体集)。(这与 SOAP 不同,因为在那里您通常将 IRI 绑定到操作。)

根据Darrel Miller 的说法路径用于描述分层数据,查询字符串用于描述 IRI 中的非分层数据,但我们将路径和查询一起使用来标识 API 内的资源。

因此,基于这些,您有两种方法:

  • 您可以说,具有较少属性的同一实体可以映射到具有自己的 IRI 的新资源。在这种情况下,/movies/1?view=thin或 the/movies/1/view:thin就可以了。
    优点:
  • 根据 RDF,属性具有rdf:typerdf:Property之一rdfs:Resource,而 REST 具有与语义网络和链接数据的连接。
  • 例如,为单个属性创建 IRI 是一种常见的做法,/movies/1/title因此,如果我们可以通过单个属性来执行此操作,那么我们也可以通过属性集合来执行此操作。
  • 它类似于我们已经用于实体集合的映射减少/movies/recent:等等...唯一的区别是,通过实体集合我们减少列表或有序集,通过属性集合我们减少映射。将两者结合使用会更有趣,例如:/movies/recent/title,它可以返回最近电影的标题。

缺点:

  • 通过 RDF,一切都有其各自的rdf:type特点rdfs:Resource,也许 REST 并不遵循与 Web 文档相同的原则。

  • 我还没有发现任何关于单个属性或属性集合可以或不能被视为论文中的资源的内容,但是我可能不小心跳过了文本的该部分(相当干的东西)......

  • 您可以说具有较少属性的同一实体只是同一资源的不同表示,因此它不应该具有不同的 IRI。在这种情况下,您必须将有关首选视图的数据放入请求中的其他位置。由于 GET 请求没有主体,并且 HTTP 方法不用于存储此类内容,因此唯一可以放置它的地方是 HTTP 标头。通过长期用户特定设置,您可以将其存储在服务器上或客户端维护的 cookie 中。通过短期设置,您可以在多个标头中发送它。通过content-type标头,您可以定义自己的 MIME 类型,但不建议这样做,因为我们不喜欢仅由单个应用程序使用的数百个自定义 MIME 类型。通过content-type标头,您可以按照Doug Moscrop 的建议向 MIME 类型添加配置文件。通过标题,您可以使用Darrel Miller建议的设置。通过标题,理论上您可以执行相同的操作,但我仅通过分页遇到范围标题。 优点:preferreturn-minimalrange

  • 这当然是一种 RESTful 方法。

缺点:

  • 现有的 HTTP 框架并不总是支持提取此类标头参数,因此您必须编写自己的简短代码来执行此操作。
  • 我无法找到有关这些标头如何影响客户端和服务器端缓存机制的任何信息,因此某些浏览器可能不支持其中一些标头,并且服务器必须编写自己的缓存实现,或者找到支持标头的框架你想用。

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

根据Darrel Miller 的说法,IRI 的命名实际上并不适用于 REST。

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

  • 路径和查询都标识资源。没有区别。媒体类型可用于描述精确的语义 - vcard、活动流、原子、文本/url-列表等。我们的目标不是设计一种只能用于一个 api 的媒体类型。 (2认同)