【问题标题】:REST API versioning when using Atom for resource collections使用 Atom 进行资源集合时的 ​​REST API 版本控制
【发布时间】:2011-12-29 23:50:28
【问题描述】:

我知道这件事已经被反复讨论过,并且我已经进行了广泛的研究以了解我目前的情况,但似乎无法克服最后的障碍。

我正在为我们的应用程序设计一个自定义 REST api,并决定我想使用媒体类型进行版本控制,例如应用程序/vnd.mycompany.resource.v2+xml。我意识到这个模型的优缺点,它似乎是最灵活的。

因此我的 GET 如下所示:

=== REQUEST ===>
GET /workspaces/123/contacts?firstName=Neil&accessID=789264&timestamp=1317611 HTTP/1.1
Accept: application/vnd.mycompany.contact-v2+xml

<== RESPONSE ===
HTTP/1.1 200 OK
Content-Type: application/vnd.mycompany.contact-v2+xml
<contact>
    <name>Neil Armstrong</name>
    <mobile>+61456838435</mobile>
    <email>neil.armstrong@space.com</email>
</contact>

问题是我想使用 Atom 提要和条目来表示我的资源集合。这样我就可以利用 Atom 的搜索和分页,而不会感染我的资源或 API 结构。

如果我使用 Atom 处理我的请求,我的请求结构现在看起来像:

=== REQUEST ===>
GET /workspaces/123/contacts HTTP/1.1
Accept: application/atom+xml; type=feed;

<== RESPONSE ===
HTTP/1.1 200 OK
Content-Type: application/atom+xml; type=feed;
<feed xmlns="http://www.w3.org/2005/Atom">
   <title>Contacts Feed</title>
   <link rel="self" href="https://api.mycompany.com/workspaces/contacts"/>
   <updated>2011-11-13T18:30:02Z</updated>
   ...
   <entry>
      <title>Neil Armstrong</title>
      ...
      <content type="application/vnd.mycompany.contact-v2+xml">
          <contact>
              <name>Neil Armstrong</name>
              <mobile>+61456838435</mobile>
              <email>neil.armstrong@space.com</email>
          </contact>
      </content>
   </entry>
</feed>

使用 Atom 来表示我的资源集合,我失去了使用媒体类型进行版本控制的能力。因为媒体类型现在隐藏在 Atom 条目的内容中。

      <content type="application/vnd.mycompany.contact-v2+xml">

确定资源的媒体类型版本,同时仍利用 Atom 的强大功能进行资源收集管理的最佳做法是什么?

我的想法是我可以通过 ACCEPT 标头传递它,例如

Accept: application/atom+xml; type=feed; version=1.0

但这很令人困惑,因为您要求的是 Atom 提要的 1.0 版,而不是资源本身......

任何帮助将不胜感激!

【问题讨论】:

    标签: rest api versioning atom-feed


    【解决方案1】:

    问题是恕我直言,您误用了媒体类型。

    媒体类型为您提供有关实际负载的结构的信息,而不是负载的语义信息。 “我知道这是一个 XHTML 页面,但我不知道它是博客文章还是亚马逊上的商品。”作为一个 XHTML 页面,您知道如何从负载中取出组件并提出有趣的问题,但负载的解释不是媒体类型的一部分。

    考虑一个示例,从 Roy Fielding 的示例中转述,将 10,000 位数组作为 100x100 像素的 GIF 文件发送。 GIF,众所周知,用于发送图片,但实际上比这更简单。这是一种发送结构化二进制文件的机制,这种机制在大多数情况下都是图像。因此,在使用它发送 10,000 位数组(可能表示为 00 和 FF 的灰度图像)的这种情况下,您将受益于通用解码器 (GIF)、内置压缩的 GIF 等。

    但是,在这种情况下,它不是图片。您可以将其显示为图片,但它是无意义的图片。在这种情况下,它用于图片场景的经典语义是不相关的。好处是格式的普遍性。

    另一个例子是几年前一位工程师正在做雷达研究。因此,他会使用您在书籍等中找到的飞机的 3 视图图纸,然后使用平板电脑将它们编码到 AutoCAD 图纸中。 DWG 格式有很好的文档记录,他有代码可以阅读它们。他想要的是特定飞机的坐标和测量值。

    所以,最后他得到了一堆“毫无意义”的 AutoCAD 文件,其中只有一堆“毫无意义”的行。但事实上,他们对他的领域充满了很好的信息。 DWG 文件是媒体类型,但这些不是“CAD 图纸”。 (你能说“自发重用”吗?)

    可以通过媒体类型对某些内容进行版本控制,但这仅在媒体类型实际上发生变化时才相关。正如您所指出的,ATOM 没有变化,或者至少它没有在您的控制下发生变化,如果/当它发生变化时,您可以选择不支持新版本。但是 ATOM 并没有改变,因为它表示信息的方式,信息的编码方式,并没有改变。信息很可能会发生变化,事实上它一直在变化。每个 ATOM 提要都有不同的信息。大多数具有相似的语义(博客提要),但许多没有(例如,可能是您的场景)。

    但是您从 ATOM 提要解析和获取信息的方式不会改变。这就是媒体类型所代表的。信息的编码,而不是信息本身。

    因此,如果您想检测版本控制,请检查您的有效负载。检查它。您知道对于您的数据的 V1,例如发票编号在哪里(可能在 XPATH 中的 invoice/inv_no 处)。如果发票不在那里,那你怎么办?您 a)查看其他知名的地方(即 V2),或者,b)您抛出错误(“不管这是什么,这不是发票!”)。无论如何,您都必须这样做,因为无论版本如何,媒体类型如何,或其他任何内容,您都可能得到任何东西。

    您可以使您的有效载荷向前兼容以抵抗破坏性更改,然后版本就是利用您可以看到的所有信息的问题。如果你得到 A 和 B,那么虽然你也想得到 C 和 D,但客户可以得到更有限的信息。如果客户看到 C 和 D,他们会知道忽略 A 和 B,因为该数据已被弃用。与服务器相同。如果有东西发送 A 和 B,则暗示它是一个旧的处理模型,而不是它们沿着 C 和 D 发送。

    您可以通过 rel 名称“order”与“order_2”进行版本控制,老客户只知道使用“order”,新客户知道使用“order_2”并点击该链接。

    或者您只需在有效负载中包含一个版本标识符,这也很容易检查(尤其是因为它处于您设计的早期阶段)。

    管理版本控制的方法有很多,但媒体类型真的不应该是机制。这就是为什么这真的不是 ATOM 的“问题”。所以,这是一个观点问题。

    我在这里有另一个关于 Accept 标头的讨论:REST API having same object, but light

    这(恕我直言)与您的版本控制问题无关,但它是扩展媒体类型的一个示例。但这只是我对大多数人为什么以及如何想要“版本控制”的看法。可以做一个案例 这个案例是同样的事情,但大多数人将版本控制与服务联系起来,而不仅仅是数据表示,这在另一篇文章中主要是关于。

    最终,您的客户端和/或服务器要么足够灵活,可以处理版本化数据,要么不能。他们会(大多数情况下,他们毕竟是计算机。确定性我的海尼……)按照他们的吩咐去做。一个简单的“忽略你不知道的东西”的规则可以让你在版本控制方面走得很远,而无需将 v1 更改为 v2,无论你的编码如何。同样,“使用你所拥有的”对于灵活、宽容的服务器来说是一个很好的规则。如果您在任何一种情况下都遇到问题,那就是错误、日志、操作员和 24 小时寻呼机的用途,无论如何您都需要这些。

    【讨论】:

    • 感谢您非常详细的回复。在这个用例中,似乎没有干净的方法来启用版本控制。我污染了我的 URI (/v1/workspaces),我污染了我的请求参数 (?version=1.0),或者我用版本污染了我的媒体类型 (application/vnd.mycompany.resource.v1-xml)。我认为鉴于需要设计这个 API 的时间框架和环境,我需要选择一个方向并坚持下去。我认为使用 Atom 提要/条目来表示集合是一个好主意,将其与版本化媒体类型结合起来,并使用版本参数进行选择。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-02
    • 1970-01-01
    • 2017-03-18
    • 1970-01-01
    • 2016-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多