如何将大量数据发送到无状态RESTful检索服务

时间:2015-01-09 19:41:40

标签: rest http request stateless httpverbs

这似乎是一个非常基本的问题,如果之前已经提出这个问题,那么道歉;请指出我对任何有用资源的指示。

所以我有一个RESTful服务来检索一些数据。但是,RESTful服务需要一定数量的数据才能进行检索。这些数据可以概括为"用户上下文" data - 有关用户的信息(无论是由调用应用程序存储还是先前从其他应用程序检索),服务需要使用该信息来执行检索。

由于REST在语义上有效,因此检索内容的正确动词(HTTP方法)是GET请求。我见过的大多数示例GET请求只使用少量数据,数据在URL上传递。然而,一旦我们进入需要大量数据进行检索的服务领域,将所有信息放入URL中似乎是错误的。不仅如此,但某些组件强制执行的URL长度存在已知限制(通常大约255个字符,IIRC)。

看似可用的选项是:

  • 使用POST在请求正文中发送数据。但是,这不是语义,因为我们不是要求服务更新任何内容,只检索。
  • 将大部分信息(在我的情况下,"用户上下文")放入HTTP标头中。但是,这个"感觉错了"标题应该用于标题,而不是数据。
  • 发出多个请求以多个网址发送数据。然而,这似乎打破了无国籍目标,因为服务必须维持某种状态以将请求联系在一起。
  • 将数据写入数据库,然后向服务传递密钥以从中检索数据。但是,这会导致请求不是自包含的,并且还会导致性能瓶颈。

还有其他选择吗?这里的最佳做法是什么?

1 个答案:

答案 0 :(得分:2)

虽然没有规范限制,但HTTP标头(如请求路径(URL))的长度确实有限(请参阅下面的链接)。

可以调整或删除服务器限制,但是您要更难以与第三方系统(例如HTTP缓存)保持兼容,并且没有保证任意HTTP客户端都支持超越这些事实上的限制。

兼容地向服务器发送任意大量数据的唯一方法是通过请求体;对于标准的HTTP谓词,只有POST和PUT请求可能有正文,其中PUT在语义上与您尝试完成的内容不兼容。

除非您能保证所有必要信息始终适合URL或请求标头(考虑到上述限制),否则您应设计REST API以通过POST请求表达此需求。

错误的观念是POST动词仅用于在服务器上修改或创建内容。实际上,只是其他动词是幂等的(没有副作用,并且执行重复请求会产生重复的结果),因此POST是唯一可以满足这些需求的动词,但一般来说,POST是对于其他动词做得不好的事情,这是一个无所不能。

当GET的限制无法以其他方式解决时,POST可合法地用作检索(更多导致重定向)或处理动词。通过设置与缓存相关的响应标头,例如Cache-ControlExpires,也可以使POST响应更像GET。