我需要设计一个RESTful查询API,基于少量过滤器返回一组对象。通常用于此的HTTP方法是GET。唯一的问题是,它可能有至少十几个过滤器,如果我们将它们全部作为查询参数传递,URL就会变得相当长(足以被某些防火墙屏蔽)。
减少参数数量不是一个选项。
我能想到的一个替代方法是在URI上使用POST方法,并将过滤器作为POST正文的一部分发送。这是否违背RESTful的特性(通过POST调用来查询数据)。
有没有人有更好的设计建议?
我需要设计一个RESTful查询API,基于少量过滤器返回一组对象。通常用于此的HTTP方法是GET。唯一的问题是,它可能有至少十几个过滤器,如果我们将它们全部作为查询参数传递,URL就会变得相当长(足以被某些防火墙屏蔽)。
减少参数数量不是一个选项。
我能想到的一个替代方法是在URI上使用POST方法,并将过滤器作为POST正文的一部分发送。这是否违背RESTful的特性(通过POST调用来查询数据)。
有没有人有更好的设计建议?
记住,在REST API中,一切都取决于你的观点。
REST API中的两个关键概念是端点和资源(实体)。粗略地说,一个端点通过GET返回资源,或者通过POST和PUT接受资源等操作(或上述操作的组合)。
人们普遍认为,使用POST时,您发送的数据可能会导致新资源及其相关端点的创建,这些资源很可能不会“存在于” POST的URL下。换句话说,当您提交POST请求时,您在某个地方发送数据进行处理。POST端点并不是资源通常被找到的位置。
引用RFC 2616 (省略无关部分,突出显示相关部分):
9.5 POST
使用POST方法请求源服务器接受请求行中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": "..."
}
这个端点没有任何不符合REST的地方。它接受请求体中以数据实体的形式出现的数据(实体)。这些数据就是搜索条件——像其他DTO一样。该端点根据请求产生响应的资源(实体):搜索结果。 搜索结果资源是一个临时的资源,立即由客户端提供,无需重定向,并且不会从其他规范url中公开。
它仍然是REST,只是实体不是书籍——请求实体是书籍搜索条件,响应实体是书籍搜索结果。
BooksSearchCriteriaDTO
和BooksSearchResultsDTO
。 - Amir AbiriPOST
用于 CRUD 的 C 部分时,201 是合适的。我建议使用普通的200,或者在搜索结果为空时选择204。 - Amir Abiriimport 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/test?code=1&code=2&code=3”
@QueryParam 会自动将查询参数“orderBy=age&orderBy=name”转换为 java.util.List。