在GET请求的正文中而不是URI中包含参数是否是RESTful?

时间:2018-09-29 09:34:29

标签: rest api django-rest-framework

我有一个复杂的架构,需要复杂的API调用。对于许多资源检索,用户可能希望指定几个参数来过滤结果。对于前端开发人员来说,将所有这些参数都包含在URI中似乎很麻烦并且很困难,因此我选择将这些参数作为JSON放入请求正文中。不幸的是,这似乎与我正在使用的Web后端(Django-Rest Framework)配合得不好。这是RESTful,还是我做错了?

作为后续问题,如果我应该将参数放在URI中,我将如何表示复杂的数据片段(例如字符串列表)以及数据片段之间的关系?

2 个答案:

答案 0 :(得分:1)

  

这是RESTful,还是我做错了?

在我看来,您好像犯了一个错误。在这种情况下,权限是RFC 7231

  

GET请求消息中的有效负载没有定义的语义;在GET请求上发送有效内容正文可能会导致某些现有实现拒绝该请求。

我的解释是:缓存是网络的重要组成部分;为了使缓存能够像人们期望的那样工作,需要兼容的缓存才能将消息正文作为密钥的一部分进行管理。

可以更好地满足您需求的HTTP方法是SEARCH

  

SEARCH方法充当查询和结果集的传输机制。它没有定义查询的语义。查询的类型定义了语义。

     

SEARCH是一种安全的方法;除了执行查询并返回查询结果外,它没有其他意义。

如果这不符合您的需求,则可以查看HTTP method registry,以查看其他标准之一是否适合您的用例。

  

我将如何表示复杂的数据片段(例如字符串列表)以及数据片段之间的关系?

真正的答案是“您想要的任何方式”-原始服务器可以控制其URI空间,并且编码到其中的任何信息都可以在服务器方便使用的情况下完成。

例如,您可以考虑使用RFC 4648中定义的Base64 encodings之一

答案 1 :(得分:0)

根据我对RESTful的了解,您只能使用GETPOSTPUTPATCHDELETE

GETDELETE不应包含正文。正如@VoiceOfUnreason所提到的,这主要是因为缓存可能难以处理GET上的主体。话虽如此,如果您的结果从未被缓存过,那么根本就不必担心。 (即,从您的服务器返回Cache: no-cache和其他类似的HTTP标头。)

在查询字符串和支持列表或JSON等上没有真正的约定。如果您想保留GET,则可以使用编码的JSON字符串。除了URL的长度,没有其他问题。

http://www.example.com/?query=<encoded-json>

(编码为 只是意味着您必须正确地转义URI特殊字符,这是JavaScript encodeURICompent()函数的作用。)

URL的长度应保持在1Kb以下,以确保100%安全。您可以对此进行一些研究,我认为限制最严格的浏览器大约为2k。

如果要使用更大的查询,则应将查询还原为使用POST而不是GET。那么在这种情况下缓冲区是正常的,并且预计不会缓存答复。


现实世界中的使用(但不是借口

如果您查看Elasticsearch,将会看到他们的所有查询都接受JSON。您可以使用GETPOST发送DSL查询。任何人都可以在自己的体内接受JSON。

它们提供POST,因为大多数浏览器都不接受将正文附加到GET方法上。因此GET查询根本无法在浏览器中进行。


查询字符串中数组的示例

已经有各种各样的库,至少是PHP,增加了对参数数组的支持。在大多数情况下,这是通过在参数名称中支持 array语法来完成的。例如:

path/?var[1]=123&var[2]=456&var[3]=789

在这种情况下,这些语言会将值转换为数组。 $_GET['var'][1]随后将返回123

这不是约定,只是特定环境的扩展。