使用一长串查询参数deviseRESTful查询API

所以,我需要devise一个RESTful查询API,它基于几个filter返回一组对象。 通常的HTTP方法是GET。 唯一的问题是,它可以有至less十几个filter,如果我们把它们全部作为查询parameter passing,那么这个URL可能会变得很长(足够长的时间可以被一些防火墙阻止)。

减less参数的数量不是一个选项。

我可以想到的一个替代方法是在URI上使用POST方法,并将filter作为POST主体的一部分发送。 这是反对RESTfull(进行POST调用查询数据)。

任何人有更好的devisebuild议?

谢谢

很多人已经接受这样一种做法:具有太长或太复杂的查询string(例如,查询string不能轻易处理嵌套数据)的GET可以作为POST发送,而在主体中表示复杂/长的数据的要求。

在HTTP规范中查找POST规范。 这是非常广泛的。 (如果你想通过REST中的漏洞航行战舰……请使用POST。)

你失去了GET语义的一些好处…比如自动重试,因为GET是幂等的,但是如果你能忍受,那么用POST来接受处理很长或者复杂的查询可能会更容易一些。

(大声笑长题外话…我最近发现,通过HTTP规范,GET 可以包含一个文档主体,有一个部分说:“任何请求可以有一个文档主体,除了在本节列出的”…而且它所指的部分没有列出任何内容,我查找并find了一个HTTP作者正在谈论的线程,这是故意的,所以路由器等不必区分不同的消息。实践中很多基础设施部分都放弃了GET的主体,所以你可以使用体内表示的filter(比如POST),但是你会掷骰子。)

请记住,使用REST API,这都是您的观点。

REST API中的两个关键概念是端点和资源(实体)。 宽松地说,一个端点或者通过GET返回资源,或者通过POST和PUT等等(或者上面的组合)接受资源。

可以接受的是,通过POST,您发送的数据可能会导致创build新的资源及其关联的terminal,而这些terminal很可能不会在POSTurl下“生存”。 换句话说,当你POST时你发送数据的地方进行处理。 POST端点不是通常可以find资源的位置。

引用RFC 2616 (省略不相关的部分,并强调相关部分):

9.5 POST

POST方法用于请求源服务器接受请求中包含的实体作为Request-Line中Request-URI标识的资源的新下属。 POST被devise为允许统一的方法来覆盖以下function:

  • 向数据处理过程提供一组数据,例如提交表单的结果;

POST方法执行的操作可能不会导致可以通过URI标识的资源 。 在这种情况下,根据响应是否包含描述结果的实体, 200(OK)或204(无内容)是适当的响应状态。

如果在原始服务器上创build了一个资源,响应应该是201(创build)…

我们已经习惯了代表“事物”或“数据”的terminal和资源,无论是域,用户,消息,还是书籍。 但是,端点也可以公开不同的资源,例如search结果。

考虑下面的例子:

GET /books?author=AUTHOR POST /books PUT /books/ID DELETE /books/ID 

这是一个典型的REST CRUD。 但是,如果我们添加:

 POST /books/search { "keywords": "...", "yearRange": {"from": 1945, "to": 2003}, "genre": "..." } 

这个端点没有任何不可靠的东西。 它以请求主体的forms接受数据(实体)。 这个数据就是search标准 – 一个DTO和其他的一样。 此端点响应请求生成一个资源(实体): search结果 。 search结果资源是临时的,不需要redirect就可以立即提供给客户端,也不会被其他规范的URL所暴露。

它仍然是REST,除了实体不是图书 – 请求实体是书籍search条件,而响应实体是书籍search结果。

简而言之:使用X-HTTP-Method-Override标头来进行POST,但覆盖HTTP方法。

真正的要求

POST /书籍

实体

{“title”:“Ipsum”,“year”:2017}

X-HTTP-Method-Override:GET

在服务器端,检查是否存在标题X-HTTP-Method-Override,然后将其值作为构build到后端最terminal点的path的方法。 另外,将实体主体作为查询string。 从后端angular度来看,请求变成了一个简单的GET。

这样你就可以保持devise与REST原则一致。

编辑:我知道这个解决scheme最初是为了解决一些浏览器和服务器中的PATCH动词问题,但是在问题中描述的很长的URL的情况下,它也适用于GET动词。