这似乎是一个很基本的问题,如果之前有人问过这个问题,请向我指出任何有用资源的方向。
所以我有一个restful服务来检索一些数据。然而,restful服务需要一定数量的数据才能进行检索。这些数据可以粗略地概括为“用户上下文”数据——关于用户的信息(无论是由调用应用程序存储的还是以前从另一个应用程序检索的),服务需要使用这些信息来执行检索。
因为rest在语义上起作用,所以检索某些内容的正确动词(http方法)是get请求。我所看到的大多数示例get请求只使用少量数据,数据通过url传递。然而,一旦我们进入需要大量数据进行检索的服务领域,将所有这些信息放在url中似乎是错误的。不仅如此,某些组件(通常255个字符左右,iirc)对url长度也有已知的限制。
似乎可用的选项有:
使用post发送请求正文中的数据。但是,这不是语义性的,因为我们不要求服务更新任何内容,只要求检索。
把大部分信息(在我的例子中是“用户上下文”)放到一个http头中。然而,这“感觉不对劲”,因为头应该用于头,而不是数据。
发出多个请求以多个URL发送数据。然而,这似乎打破了无状态的目标,因为服务必须保持某种状态才能将请求绑定在一起。
将数据写入数据库,然后向服务传递一个密钥以从中检索数据。但是,这将导致请求不自包含,并引入性能瓶颈。
还有别的选择吗?这里的最佳做法是什么?
最佳答案
虽然不受规范限制,但HTTP头(如请求路径(URL))的实际长度是有限的(请参阅下面的链接)。
Discussion of URL length
Discussion of Header length
您可以调整或删除服务器限制,但这样就很难与第三方系统(如http缓存)保持兼容,而且也不能保证任意http客户端支持超过这些事实上的限制。
兼容地向服务器发送任意大量数据的唯一方法是通过请求体;在标准http动词中,只有post和put请求可能具有体,其中,put在语义上与您试图完成的任务不兼容。
除非您能够保证所有必要的信息始终适合url或请求头(考虑到上述限制),否则您应该设计rest api,通过post请求来表达这种需要。
有一种误解,认为post动词只用于修改或创建服务器上的某些内容。实际上,只是其他动词是等幂的(没有副作用,执行重复的请求会产生重复的结果),因此post是唯一能满足这些需要的动词,但一般来说,post是其他动词做不好的所有事情的全部。
当get的限制无法解决时,post可以合法地用作检索(更多地导致重定向)或处理动词。post响应也可以通过设置与缓存相关的响应头(如Cache-Control
和Expires
)使其行为更像get。
关于rest - 如何将大量数据发送到无状态RESTful检索服务,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27867987/