所以,我需要设计一个RESTful查询API,它返回一组基于几个过滤器的对象。 这种情况的通常的HTTP方法是GET。 唯一的问题是,它可以有至少有十几个过滤器,如果我们通过它们作为查询参数的URL可以得到相当长的(足够长的时间来通过一些防火墙阻止)。
减少参数的数量是不是一种选择。
一种替代我能想到的是使用中的URI,POST方法和发送过滤器作为POST身体的一部分。 这是对是问题的REST(拨打POST调用查询数据)。
任何人有任何更好的设计建议?
谢谢
所以,我需要设计一个RESTful查询API,它返回一组基于几个过滤器的对象。 这种情况的通常的HTTP方法是GET。 唯一的问题是,它可以有至少有十几个过滤器,如果我们通过它们作为查询参数的URL可以得到相当长的(足够长的时间来通过一些防火墙阻止)。
减少参数的数量是不是一种选择。
一种替代我能想到的是使用中的URI,POST方法和发送过滤器作为POST身体的一部分。 这是对是问题的REST(拨打POST调用查询数据)。
任何人有任何更好的设计建议?
谢谢
请记住,一个REST API,这是你的观点的所有问题。
在REST API的两个关键概念是端点和资源(实体)。 通过GET松散放置,端点或者返回资源或通过POST接受资源和PUT等(或上述的组合)。
一般认为,与邮政,您发送的数据可能会或可能不会导致创建一个新的资源和其相关联的端点(S),这将最有可能不是“活”张贴的URL下。 在当您发布换句话说,你处理的地方发送数据。 该POST端点不是在资源通常可能被发现。
从引用的RFC 2616 (与不相关部分省略,并且相关部分突出显示):
9.5 POST
POST方法用来请求原始服务器接受被附在请求由请求URI中使用Request-Line标识的资源的新下属的实体。 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": "..."
}
没有什么非REST风格的这个端点。 它接受在请求主体的形式数据(实体)。 这些数据是搜索条件 -像任何其他DTO。 该端点产生响应于所述请求的资源(实体): 搜索结果 。 搜索结果资源,立即提供给客户端,如果没有重定向,没有从其他一些规范的网址被暴露是暂时的。
它仍然休息,除了实体不是书 - 请求实体书的搜索条件,响应实体书的搜索结果。
很多人已经接受的做法,随着时间过长或过于复杂的查询字符串GET(如查询字符串不处理容易嵌套数据)可以作为一个POST改为发送,在体内代表的复杂/长数据的请求。
查找的POST规范的HTTP规范。 这是令人难以置信的宽广。 (如果你想通过REST漏洞帆战舰......使用POST)。
你失去了一些GET语义的待遇,如自动重试,因为GET是幂等的,但如果你可以忍受的,它可能更容易只接受与后期处理很长的或复杂的查询。
(笑长题外话......我最近发现,通过HTTP规范,GET 可以包含文档的身体。还有一个节说,释义,“任何请求都可以有一个文档主体除了在本节中列出的” ...它指的是部分没有列出任何,我搜索,发现那里的HTTP提交人谈论的一个线程,这是故意的,让路由器和这样不会有不同的消息之间进行区分。然而,多多练习的基础件不掉落GET的身体。所以,你可以用在身体表示,像后置滤波器GET,但你会掷骰子)。
简而言之:使一个POST,但使用X-HTTP-方法-Override标头重写的HTTP方法。
真正的要求
POST /书籍
实体主体
{ “称号”: “存有”, “年”:2017年}
头
X-HTTP-方法 - 覆盖:GET
在服务器端,检查是否头X-HTTP-方法-覆盖存在,那么采取其值作为建立到在后端终端点的路由的方法。 此外,采取实体主体作为查询字符串。 从一个后端点,请求成为只是一个简单的GET。
这使得你可以设计在和谐与REST原则。
编辑:我知道这个解决方案最初打算在一些浏览器和服务器解决PATCH动词的问题,但它也为我GET动词在很长的URL这是在提到的问题的情况下工作。
如果您在Java和JAX-RS开发,我建议你使用@QueryParam与@GET
我有同样的问题,当我需要经过一个列表。
见例如:
import java.util.List;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
@Path("/poc")
public class UserService {
@GET
@Path("/test/")
@Produces(MediaType.APPLICATION_JSON)
public Response test(@QueryParam("code") final List<Integer> code) {
Integer int0 = codigo.get(0);
Integer int1 = codigo.get(1);
return Response.ok(new JSONObject().put("int01", int0)).build();
}
}
URI图样:?“POC /测试代码= 1&代码= 2&代码= 3
@QueryParam将查询参数“排序依据=年龄与ORDERBY =名称为”自动转换为java.util.List的。