【问题标题】:Why do we need a custom media type when using hypermedia links?为什么我们在使用超媒体链接时需要自定义媒体类型?
【发布时间】:2013-04-10 15:00:42
【问题描述】:

我目前正在设计一个纯粹面向资源的企业服务。在阅读了几篇博客、书籍等之后。我相信带有超媒体链接的 REST 是要走的路。

然而,所有这些博客和书籍都说的一件事是在响应中使用超媒体链接时不要使用 application/xml 作为媒体类型。他们都没有说明原因,除了一个通用的声明,比如没有链接关系类型的普通 URI 不会将 URI 的语义传达给客户端。

据我了解,这是一种推荐的方法来定义您自己的自定义媒体类型并让客户知道如何阅读它。但是如果知道连接到我的服务的客户端永远不会是浏览器,这有关系吗?我不能在我的响应中使用 application/xml 类型公开这些链接吗?

我希望这里有人能详细说明一下。

【问题讨论】:

    标签: rest hypermedia mediatypeformatter


    【解决方案1】:

    这是我能想到的最佳答案...我最近联系了菲尔丁博士以验证我的理解,但尚未收到回复。如果他对我大喊大叫,我会修改它。

    我怀疑,正如 Darrel Miller 所拥有的 alluded to,目标应该是避免创建过于具体的类型 - 毕竟,它拥有 been said

    REST API 绝不应该包含对 客户。

    我觉得互联网上大多数与 REST 相关的超媒体内容基本上都违反了这一原则,并将人们引向了错误的方向——因为它们引入了非常具体的“限定词”(我将提到它们)来他们的资源。

    您会看到诸如 application/vnd.com.foo.bar+xmlapplication/vnd.com.example.thing+json 之类的东西 - 有些人决定不使用类型本身,而是使用参数,例如application/xml; someKey=someValue——在我看来,这与资格没有什么不同。对我来说,这是一个类型化的资源

    text/html 是超文本的缩影是有原因的 - 浏览器有一个 处理指令 用于理解这种媒体类型。不仅是渲染和布局,而且强大的交互先例是由 HTML 规范设置的(例如,锚标记导致检索,表单可以通过编码触发提交等),正是由于这个原因,这种非常通用、非常强大的超媒体类型已经允许我们今天使用的所有网页在您的浏览器和提供它们的服务器之间没有任何耦合的情况下存在 - 唯一需要的是了解 HTML 作为内容类型是什么。

    这对 API 意味着什么?这意味着为某些资源、某些特定 URI(或它们的集合)创建特定的内容类型并不能稳健地使用超媒体,并且可能意味着您具有 REST 试图避免的那种客户端-服务器耦合。这也意味着application/xml 等是贫血的——它们有 parsing 指令,但没有 processing 指令。设计良好的 REST API 将具有更通用的超媒体类型,不是为特定资源创建的,而是明确定义潜在客户必须了解才能参与的处理指令。

    有趣的——当然也可能有争议——text/html 已经有很多这样的东西了——为什么不使用它呢?我们的 API 消费者想要 HTML 以外的东西(例如,他们认为 JSON 或 XML 格式是灵丹妙药)的事实实际上是由于对拥有超媒体驱动的应用程序引擎意味着什么存在固有的误解 - 即它的处理指令表示应该是相当通用的。当然,您可以使用 XML 做到这一点,只需让您的 API 定义一组清晰的元素及其含义即可。使用 HTML 的部分只是为了说明一点。

    有抱负的 REST API,即使有一组丰富的超链接来表达通过资源的状态转换,也可能——而且似乎最常见的情况——无法实现 REST 真正涉及的可扩展、长期存在的架构风格。

    【讨论】:

    • 我的回答很糟糕。不是 REST 对您的媒体类型的具体程度有任何意见,更多的是 REST 社区担心媒体类型的爆炸式增长。我不太关心特定的媒体类型,而更关心创建仅对一个 API 有用的媒体类型的人。我希望看到创建的许多媒体类型可以在许多 API 中重复使用。
    • 我认为您过度解释了 API 不应该有类型资源的 Fielding 的含义。该段继续说“对客户重要的唯一类型是当前表示的媒体类型和标准化关系名称。”媒体类型是类型。我认为如果您执行 GET /Customer 并获取 application/xml 并返回您不能假设在该 XML 中序列化了 Customer 类型。
    • 总的来说,我同意你所说的。我会避免使用术语“处理指令”,因为 application/xml 确实定义了这个概念。我认为超媒体控件对于 app/xml 中缺少的内容来说是一个更好的术语。然而,HTML 并不是唯一能够创建 RESTful 系统的格式。 Collection+json 和 HAL 是两种相当新的格式,结合链接关系可以非常有效。
    • 我不确定——如果你过度指定资源的媒体类型,那么你实际上是在创建一个静态类型的接口,不是吗? HTML 是超文本和 REST 的缩影,因为它是网络的统一界面。我不希望我的浏览器必须比“应用程序/客户”更了解“应用程序/银行帐户”。有道理? HTML 中的超媒体控件非常非常通用。我相信我们可能需要特定应用程序域中的某个子集,而不是资源级别的子集。
    • 同意 - 我已经查看了您的博客,我将继续这样做。这很有趣,因为我与一位同事进行了一次边谈,并同意 HTTP 可以被认为是 WWW 作为互联网之上的应用程序的统一接口。无论哪种方式,我认为我们应该获得一个新的 Stack Overflow 徽章:[讨论 REST 而不会互相争论或侮辱] 干杯 :)
    【解决方案2】:

    您不必使用自定义媒体类型。事实上,REST 试图阻止人们创建过于具体的媒体类型。理想的情况是媒体类型应该传达语义信息,而不是特定于任何特定服务。

    application/xml 的一个问题是它对链接的外观没有标准定义。是吗

    <Link rel="foo" href="/foo">

    是吗

    <foo href="/foo">

    或其他一些变体?您的客户如何知道如何在不使用“带外”知识的情况下识别文档中存在哪些链接? “带外”知识是您要避免的,因为它会导致客户端在服务器进行更改时中断,并且客户端无法保护自己免受带外知识的更改。

    application/xml 的另一个问题是它除了元素和属性的层次结构之外不包含任何语义。语义要么必须通过媒体类型或链接关系来传达。如果您使用application/xml,那么您必须使用链接关系来告诉客户端如何使用该文档。

    在链接关系和媒体类型中传达语义之间可以有一个很好的平衡。但老实说,整个行业都在试图弄清楚这种平衡到底是什么,而且有很多人对这个问题有不同的看法。

    我建议查看application/hal+xml。它最接近通用 XML,但定义了链接语义。

    【讨论】:

    • +1 好帖子——尽管我认为问题不在于application/xml 不包含“标准”链接类型——真的,这是您的 API 规范所关心的问题.客户必须实施您决定的任何处理指令。我认为 真正的 问题,正如我在回复中所说的那样,似乎没有人能够提出与 text/html 提供的灵活性相当的处理指令(这让我想知道,为什么我们不将 HTML 用于我们的 API?大量的开源代码,客户端不必实际渲染任何东西。值得深思。)
    • 另外,我不同意你的带外知识点。 format 不是这里的问题——否则我可以争辩说,HTML 需要“带外”知识来了解锚元素是什么,或者输入元素是什么。这些东西被明确定义为 HTML 处理模型的基础。您的 API 也应该如此——但它应该是灵活的。 JSON/XML/YAML 不是问题,因为它们的格式是灵活的,它们是一个问题,因为它们没有为超媒体控件定义明确的指令。 (这些不仅仅是只是超链接)。
    • @Doug Jon Moore 和 Mike Amundsen 都有许多关于将 xhtml 用于 API 的文章/视频。这是一种很常见的方法。 HTML 不需要带外链接知识,因为 Content-Type 标头指向 text/html 而 IANA 注册指向定义链接语法的 HTML 规范。 application/xml 规范没有。
    • 我会检查一下 - 谢谢!我不知道这很常见,但无论如何我怀疑不乏有人会双重接受这样一个概念(特别是如果它来自非权威来源或其他任何人,例如我自己) “什么?那是浏览器的布局信息!”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-17
    • 2012-12-20
    • 1970-01-01
    • 2015-08-22
    • 1970-01-01
    • 1970-01-01
    • 2013-05-11
    相关资源
    最近更新 更多