如何处理 HTTPGET 查询字符串长度限制而仍然希望是 RESTful 的?

http://www.boutell.com/newfaq/misc/urllength.html所述,HTTP 查询字符串的长度是有限的。它可以受到客户端(Firefox,IE,...)、服务器(Apache,IIS,...)或网络设备(应用防火墙,...)的限制。

今天我用搜索表单面对这个问题。我们开发了一个包含很多字段的搜索表单,这个表单作为 GET 请求发送到服务器,因此我可以将结果页面加入书签。

我们有如此多的字段,以至于我们的查询字符串长度为1100字节,并且我们有一个防火墙,它删除超过1024字节的 HTTP GET 请求。我们的系统管理员建议我们使用 POST,这样就没有限制了。

当然,POST 将工作,但我真的觉得作为一个 GET 而不是一个 POST 的搜索。因此,我认为我将检查我们的字段名,以确保查询字符串不会太长,如果不能,我将是务实的,并使用 POST。

但是 RESTful 服务的设计是否存在缺陷?如果 GET 请求的长度有限,那么如何将大型对象发送到 RESTful Web 服务呢?例如,如果我有一个基于文件进行计算的程序,并且我想提供一个 RESTful Web 服务,如下所示: http://compute.com?content=<base64 file>。这不会起作用,因为查询字符串没有无限长度。

我有点困惑。

66199 次浏览

REST is a manner to do things, not a protocol. Even if you dislike to POST when it is really a GET, it will work.

If you will/must stay with the "standard" definition of GET, POST, etc. than maybe consider to POST a query, that query will be stored on the server with a query id and request the query later with GET by id.

HTTP specification actually advises to use POST when sending data to a resource for computation.

Your search looks like a computation, not a resource itself. What you could do if you still want your search results to be a resource is create a token to identify that specific search result and redirect the user agent to that resource.

You could then delete search results tokens after some amount of time.

Example

POST /search
query=something&category=c1&category=c2&...


201 Created
Location: /search/01543164876

then

GET /search/01543164876


200 Ok
... your results here...

This way, browsers and proxies can still cache search results but you are submitting your query parameters using POST.

EDIT

For clarification, 01543164876 here represents a unique ID for the resource representing your search. Those 2 requests basically mean: create a new search object with these criteria, then retrieve the results associated with the created search object.

This ID can be a unique ID generated for each new request. This would mean that your server will leak "search" objects and you will have to clean them regularly with a caching strategy.

Or it can be a hash of all the search criteria actually representing the search asked by the user. This allows you to reuse IDs since recreating a search will return an existing ID that may (or may not) be already cached.

Based on your description, IMHO you should use a POST. POST is for putting data on the server and, in some cases, obtain an answer. In your case, you do a search (send a query to the server) and get the result of that search (retrieve the query result).

The definition of GET says that it must be used to retrieve an already existing resource. By definition, POST is to create a new resource. This is exactly what you are doing: creating a resource on the server and retrieving it! Even if you don't store the search result, you created an object on the server and retrieved it. As PeterMmm previsouly said, you could do this with a POST (create and store the query result) and then use a GET to retrive the query, but it's more pratical do only a POST and retrieve the result.

Hope this helps! :)

Regarding your example:http://compute.com?content={base64file}, I would use POST because you are uploading "something" to be computed. For me this "something" feels more like a resource as a simple parameter.

In contrast to this in usual search I would start to stick with GET and parameters. You make it so much easier for api-clients to test and play around with your api. Make the read-only access (which in most cases is the majority of traffic) as simple as possible!

But the dilemma of large query strings is a valid limitation of GET. Here I would go pragmatic, as long as you don't hit this limit go with GET and url-params. This will work in 98% of search-cases. Only act if you hit this limit and then also introduce POST with payload (with mime-type Content-Type: application/x-www-form-urlencoded).

Have you got more real-world examples?

The confusion around GET is a browser limitation. If you are creating a RESTful interface for an A2A or P2P application then there is no limitation to the length of your GET.

Now, if you happen to want to use a browser to view your RESTful interface (aka during development/debugging) then you will run into this limit, but there are tools out there to get around this.

This is an easy one. Use POST. HTTP doesn't impose a limit on the URL length for GET but servers do. Be pragmatic and work around that with a POST.

You could also use a GET body (that is allowed) but that's a double-whammy in that it is not correct usage and probably going to have server problems.

I think if u develop the biz system, encounter this issue, u must think whether the api design reasonable, if u GET api param design a biz_ids, and it too long.

u should think about with UI or Usecase, whether use other_biz_id to find biz_ids and build target response instead of biz_ids directly or not.

if u old api be depended on, u can add a new api for this usecase, if u module design well u add this api may fast.

I think should use protocols in a standard way as developer. hope help u.