HATEOAS是否暗示查询字符串不是RESTful?

时间:2011-01-05 07:35:41

标签: rest hateoas

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”。

6 个答案:

答案 0 :(得分:7)

在Roy Fielding的own words中(文章的第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 templates的详细信息,请查看RFC6570

答案 1 :(得分:5)

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

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

答案 2 :(得分: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自己的this quote

  

REST不要求URI   不透明。这个词唯一的地方   不透明发生在我的论文中   在哪里我抱怨不透明   的饼干。事实上,RESTful   应用程序始终是   鼓励使用有意义的,   分层标识符以便   最大化偶然使用的   超出预期的信息   原始申请。

答案 3 :(得分:2)

我没有看到查询字符串与状态跟踪有什么关系。 HATEOAS原则的要点是避免跟踪客户端上的状态,从“作弊”和转到“已知”数据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的把握非常微弱,我的回答主要是为了解决问题并得到反馈。当然有更好的答案。

答案 4 :(得分:2)

没有HATEOAS并不意味着查询字符串不是RESTful。实际上恰恰相反。

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

以下是在URL中存储客户端状态的另一个示例:http://yuml.me/diagram/scruffy/class/ [Company] <&gt; -1&gt; [Location],[Location] + - &gt; [点]

答案 5 :(得分:0)

要跟进Darrel所说的内容,您无需更改URL以包含第二个URL。

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