11

几天来,我一直在阅读“真正的”RESTful API,我我已经接近于摸索它的内容了。

但我偶然发现的一件事是,我什至无法想象如何为“真正的”超媒体 API 编写客户端:

  1. 我读过的大多数例子都是关于浏览器和蜘蛛的,但这并不是特别有用:一个是人为导向的“智能”,另一个是愚蠢和“随机”的。就目前而言,我的印象是你需要学习人工智能才能让客户工作。

  2. 我不清楚的一件事是客户如何知道在任何给定链接上使用哪个动词?这是否隐含在 uri 的“rel”类型中?另一种选择(在这里阅读)似乎是使用 xhtml 并拥有一个可以解析和发布表单的客户端。

  3. 链接改变的可能性有多大,但链接的路径不会改变?在您看到的大多数示例中,路由和链接是相同的:

例如。如果我想建立一个客户端,它将把我从 Toni's Cake Shop 带回来的蛋糕列表:

http://tonis.com
{ link: { type : "cakes" ; uri : "http://tonis.com/cakes" } }

当 Toni's 变成 Toni's Food Shop 并且链接变成 时会发生http://tonis.com/desserts/cakes什么?

我们是否将初始cakes链接保留在根目录以实现反向兼容性?如果没有,我们如何为被告知“去根,寻找蛋糕”的可怜的小代理进行“重定向”?

我错过了什么?

4

2 回答 2

10

好吧,我也不是 REST 专家,我最近一直在阅读很多相关的东西,所以我要写的不是我的经验或意见,而是我所读内容的总结,尤其是REST In Practice书。

首先,您无法避免在客户端和服务器之间达成一些初步协议,REST 的目标是让他们在与他们双方相关的最起码的事情上达成一致,并让每一方都关心自己的事情他们自己。例如,客户端不应该关心链接布局或数据如何存储在服务器上,服务器不应该关心客户端的状态。他们事先(即在交互开始之前)达成一致的是上述书的作者所说的“域应用协议”(DAP)。

DAP 的重要之处在于它是有状态的,即使 HTTP 本身不是(因为任何客户端-服务交互至少有状态,开始和结束)。这种状态可以用“客户下一步可以/可能/预期做什么”来描述:“我已经开始使用服务,现在怎么办?好的,我可以搜索项目。搜索这个项目,下一步是什么?好的,我可以点这个那个……等等”

超媒体内容类型的定义是能够处理数据交换和交互状态。正如我已经提到的,状态是根据可能的操作来描述的,并且来自 REST 中的“资源”,所有操作都是根据可访问资源来描述的。我想,您已经看到了首字母缩略词“HATEOAS(超媒体作为应用程序状态的引擎),所以这显然是这个意思。

因此,为了与服务交互,客户端使用他们都理解的超媒体格式,可以是标准的、本土的或这些的混合(例如基于 XML/XHTML)。除此之外,他们还必须共享协议,这很可能是 HTTP,但是由于标准中省略了一些细节,因此必须有一些使用习惯,例如“使用 POST 创建资源和 PUT 更新” . 此外,此类协议将包括服务的入口点(同样,在可访问资源方面)。

这三个方面完全定义了域协议。特别是,客户端在开始使用服务之前不应该知道任何内部链接,或者在交互完成后记住它们。因此,只要客户遵守初始协议并通过前门进入商店,内部导航的任何更改(例如重命名/cakes为)都不会影响客户。/f5d96b5c

于 2012-03-09T18:45:41.147 回答
8

@Benjol

您必须避免针对特定 URI 对客户端进行编程。当你描述一个链接时,主要的意义在于它的意义,而不是 URI 本身。您可以随时更改 URI,但这不会破坏您的客户端。

我会这样改变你的例子:

{"link": {
  "rel":   "collection http://relations.your-service.com/cakes",
  "href":  "http://tonis.com/cakes",
  "title": "List of cakes",
  "type":  "application/vnd.yourformat+json"
}}

如果有一个客户端使用你的服务,它需要了解:

  • 链接结构本身
  • 链接关系(在这种情况下,“collection”是 RFC,“http://relations.your-service.com/cakes”是您的域特定链接关系)

在这种情况下,客户端只需取消引用“href”属性指定的地址并显示蛋糕列表。稍后,如果您更改蛋糕列表提供者 URI,客户端将继续工作,这意味着客户端仍然理解您的媒体类型的语义。

附言

于 2012-06-01T17:31:01.233 回答