使用一长串查询参数设计RESTful查询API
所以,我需要设计一个RESTful查询API,它基于几个过滤器返回一组对象。 通常的HTTP方法是GET。 唯一的问题是,它可以有至少十几个过滤器,并且如果我们将它们全部作为查询参数传递,URL可能会变得很长(足够长以被防火墙阻止)。
减少参数数量不是一种选择。
我能想到的另一种方法是在URI上使用POST方法,并将过滤器作为POST主体的一部分发送。 这是反对RESTfull(进行POST调用查询数据)。
任何人有更好的设计建议?
谢谢
请记住,使用REST API,这都是您的观点问题。
REST API中的两个关键概念是端点和资源(实体)。 宽松地说,端点通过GET返回资源或通过POST和PUT等(或上述组合)接受资源。
可以接受的是,通过POST,您发送的数据可能会或可能不会导致创建新资源及其关联的终端,而这些终端很可能不会在POST网址下“活”。 换句话说,当你POST时你发送数据的地方进行处理。 POST端点不是通常可以找到资源的位置。
引用RFC 2616(省略不相关的部分,并强调相关部分):
9.5 POST
POST方法用于请求源服务器接受请求中包含的实体作为Request-Line中Request-URI标识的资源的新下属。 POST旨在允许统一的方法来涵盖以下功能:
...
POST方法执行的操作可能不会导致可以通过URI标识的资源 。 在这种情况下,200(OK)或204(无内容)是适当的响应状态,具体取决于响应是否包含描述结果的实体 。
如果在原始服务器上创建了一个资源,那么响应应该是201(创建)...
我们已经习惯了代表“事物”或“数据”的终端和资源,无论是域,用户,消息还是书籍。 但是,端点也可以公开不同的资源 - 例如搜索结果。
考虑下面的例子:
GET /books?author=AUTHOR
POST /books
PUT /books/ID
DELETE /books/ID
这是一个典型的REST CRUD。 但是,如果我们添加:
POST /books/search
{
"keywords": "...",
"yearRange": {"from": 1945, "to": 2003},
"genre": "..."
}
这个端点没有什么不可靠的。 它以请求主体的形式接受数据(实体)。 该数据是搜索标准 - 与其他任何DTO一样。 该端点响应请求产生资源(实体): 搜索结果 。 搜索结果资源是一个临时的资源,立即向客户端提供,没有重定向,也没有从其他规范网址公开。
它仍然是REST,除了实体不是书籍 - 请求实体是书籍搜索条件,并且响应实体是书籍搜索结果。
许多人已经接受这样一种做法:具有太长或太复杂查询字符串的GET(例如,查询字符串不能轻松处理嵌套数据)可以作为POST发送,而用体内表示的复杂/长数据的请求。
在HTTP规范中查找POST规范。 它非常广泛。 (如果你想通过REST中的漏洞航行战舰......请使用POST。)
你失去了GET语义的一些好处,比如自动重试,因为GET是幂等的,但是如果你能忍受,那么接受POST处理真正长或复杂的查询可能会更容易。
(大声笑长题外话......我最近发现,通过HTTP规范,GET可以包含一个文档主体,有一个部分说,解释说:“任何请求可以有一个文档主体,除了本节中列出的文档主体”...并且它所指的部分没有列出任何内容我搜索并找到了一个HTTP作者正在谈论的线程,这是故意的,以便路由器等不必区分不同的消息。实践中很多基础设施部分都会抛弃GET的主体,因此您可以使用体内代表的过滤器进行GET,例如POST,但是您会掷骰子。)
简而言之:使用X-HTTP-Method-Override标题创建POST但覆盖HTTP方法。
真正的要求
POST /书籍
实体主体
{“title”:“Ipsum”,“年份”:2017}
头
X-HTTP-Method-Override:GET
在服务器端,检查是否存在标题X-HTTP-Method-Override,然后将其值作为构建到后端最终端点的路径的方法。 另外,将实体主体作为查询字符串。 从后端角度来看,请求变成了一个简单的GET。
通过这种方式,您可以使设计与REST原则保持一致。
编辑:我知道这个解决方案最初是为了解决某些浏览器和服务器中的PATCH动词问题,但在问题中描述的问题很长的URL的情况下,它也适用于GET动词。
链接地址: http://www.djcxy.com/p/71375.html上一篇: Design RESTful query API with a long list of query parameters