13

HATEOAS(作为应用程序状态引擎的超媒体)建议是否暗示查询字符串不是 RESTful?

编辑:下面建议查询字符串可能与状态没有太大关系,因此这个问题令人费解。我建议除非客户端填写参数,否则 URI 具有查询字符串是没有意义的。如果客户端正在填写参数,那么它就是在掺假服务器提供的 URI,我想知道这是否违反了 RESTful 原则。

编辑 2:我意识到如果客户端将其视为不透明的查询字符串似乎是无害的(并且查询字符串可能是遗留的,因此很方便)。但是,在下面的答案之一中,引用了 Roy Fielding 的话说,应该将 URI 视为透明的。如果它是透明的,那么我认为鼓励掺假,这似乎淡化了 HATEOAS 原则。这种稀释是否仍然与 HATEOAS 一致?这就提出了一个问题,即 REST 是否需要像 URI 构建那样紧密耦合。

更新在这个 REST 教程http://rest.elkstein.org/建议 URI 构建是糟糕的设计并且不是 RESTful。它还迭代了@zoul 在接受的答案中所说的内容。

例如,“产品列表”请求可以返回每个产品的 ID,并且规范说您应该使用http://www.acme.com/product/PRODUCT_ID来获取更多详细信息。那是糟糕的设计。相反,响应应该包含每个项目的实际 URL:http://www.acme.com/product/001263等。是的,这意味着输出更大。但这也意味着您可以根据需要轻松地将客户引导到新的 URL

如果一个人正在查看此列表并且不想要他/她可以看到的内容,则可能会有一个“前 10 个项目”和一个“下一个 10 个项目”按钮,但是,如果没有人,而是一个客户端程序, REST 的这一方面似乎有点奇怪,因为客户端程序可能没有使用所有“ http://www ”。

4

6 回答 6

7

用 Roy Fielding自己的话来说(文章中的第 4 个要点):

REST API 不得定义固定的资源名称或层次结构(客户端和服务器的明显耦合)。服务器必须可以自由控制自己的命名空间。相反,允许服务器通过在媒体类型和链接关系中定义这些指令来指导客户端如何构建适当的 URI,例如在 HTML 表单和 URI 模板中完成。

换句话说,只要客户端没有得到他们需要在带外信息中生成 URI 的片段,就不会违反 HATEAOS。


请注意, URI 模板也可以在没有查询字符串的 URI 中使用:

http://example.com/dictionary/{term}

所以问题更多是关于允许客户端构造 URL 是否是 RESTful,而不是使用查询字符串是否是 RESTful。

请注意,在上面的示例中,提供给客户端的信息量与提供所有可能术语的详尽列表完全相同,但从带宽的角度来看,效率要高得多。

它还允许客户端在尊重 HATEAOS 的同时搜索字典,如果没有带内指令,这将是不可能的。我很有信心 Roy Fielding 不会推广没有任何搜索功能的网络......


关于您的第三条评论,我认为 Roy Fielding 是在鼓励 API 设计人员将“透明”URI 作为HATEAOS 之上的一项额外功能。我不会将他在 zoul 的回答中的引用解释为客户将使用“常识”来导航具有明确 URI 的 API 的声明。他们仍然会使用带内指令(如表单和 URI 模板)。但这并不意味着透明的 URI 并不比黑暗的、令人惊讶的、不透明的 URI 好。

事实上,透明 URI 为 API 提供了附加值(调试是我能想到的一个用例,其中透明 URI 是无价的)。


有关URI 模板的更多信息,您可以查看RFC6570

于 2013-10-08T13:27:41.117 回答
5

我的看法是,REST 本身没有说明 URI 是不透明的还是透明的,但 REST 应用程序不应依赖客户端来构造服务器尚未告知的 URI。服务器可以通过多种方式执行此操作:例如,可能包含指向其成员的链接的集合,或者具有 GET 方法的 HTML 表单显然会导致在客户端创建并获取带有参数的 URI,或者至少有几个针对 URI 模板的提议标准。REST 的重要之处在于,有效 URI 的描述应该由服务器在它给客户端的响应中以某种方式定义,而不是在一些带外 API 文档中

URI 透明度是一件好事,就像任何地方的透明度都是一件好事一样——它促进并允许对资源的新颖和计划外的使用超出设计者最初的想象——但是(至少在我的理解中)不需要好的URI将接口描述为 RESTful

于 2011-01-05T15:31:57.567 回答
4

我建议除非客户端填写参数,否则 URI 具有查询字符串是没有意义的。

这对我来说似乎不是真的。如果您向服务器索要几张照片,服务器返回如下内容是完全有效的:

<photos>
    <photo url="http://somewhere/photo?id=1"/>
    <photo url="http://somewhere/photo?id=2"/>
</photos>

您可以改用/photo/id/xx路径,但这不是重点。即使客户端不更改它们,这些 URL 也可以使用。至于你的第二点:

如果客户端正在填写参数,那么它就是在掺假服务器提供的 URI,我想知道这是否违反了 RESTful 原则。

我想这是你问题的核心。而且我认为您不必将 URL 视为不透明的标识符,请参阅Roy Fielding 本人的这句话

REST 不要求 URI 是不透明的。在我的论文中出现不透明这个词的唯一地方是我抱怨 cookie 不透明的地方。事实上,RESTful 应用程序在任何时候都被鼓励使用具有人类意义的分层标识符,以便最大限度地意外使用信息,超出原始应用程序的预期。

于 2011-01-05T14:12:53.183 回答
2

我看不出查询字符串与状态跟踪有什么关系。HATEOAS 原则的要点是避免跟踪客户端上的状态,避免“作弊”和访问“已知”URL 获取数据。这些 URL 是否有查询字符串对我来说似乎无关紧要。

哦。也许您对搜索 URL 之类的东西感兴趣,其中 URL 的某个部分必须根据搜索条件进行更改?因为这些 URL 似乎必须事先知道,从而代表我们试图用 REST 消除的带外信息?我认为这可以使用 URL 模板来解决。例子:

client -> server
    GET /items
server -> client
    /* …whatever, an item index… */
    <search by="color">http://somewhere/items/colored/{#color_id}</search>

这样你就不需要先验的 URL 知识来搜索,你应该忠实于超媒体状态跟踪原则。但是我对 REST 的掌握非常薄弱,我回答主要是为了整理脑海中的东西并获得反馈。肯定有更好的答案。

于 2011-01-05T08:24:38.137 回答
2

没有 HATEOAS 并不意味着查询字符串不是 RESTful。事实上,情况可能正好相反。

考虑常见的登录场景,用户尝试访问安全资源并将他们发送到登录屏幕。登录屏幕的 URL 通常包含一个名为 redirectUrl 的查询字符串参数,它告诉登录屏幕在成功登录后返回到哪里。这是使用 URI 维护客户端状态的示例。

这是在 URL 中存储客户端状态的另一个示例:http://yuml.me/diagram/scruffy/class/[Company]<>-1>[Location], [Location]+->[Point]

于 2011-01-05T13:05:32.627 回答
0

按照 Darrel 的说法,您无需更改 URL 以包含第二个 URL。

对于基于 cookie 的身份验证,您可以在 401 响应的正文中返回登录表单,并使用空表单操作,并使用可以发布到每个资源并由每个资源处理的唯一字段名称。这样你就完全避免了重定向的需要。如果你不能让每个资源都处理登录请求,你可以让 401 表单动作指向一个登录动作资源,并将重定向 URL 放在隐藏字段中。无论哪种方式,您都可以避免在 URL 中出现丑陋的 URL,并且第一种方式避免了 RPC 登录操作和重定向的需要,从而使所有交互都集中在资源上。

于 2016-12-26T11:21:12.283 回答