【发布时间】:2010-12-29 19:18:39
【问题描述】:
我了解如何执行 GET http://localhost:8080/rest_mysql/books/1 之类的查询并使用 ID(在本例中为“1”)进行查询,但假设您想搜索具有 2 个变量而不是 1 个变量的书。这仍然可以通过获取?
【问题讨论】:
我了解如何执行 GET http://localhost:8080/rest_mysql/books/1 之类的查询并使用 ID(在本例中为“1”)进行查询,但假设您想搜索具有 2 个变量而不是 1 个变量的书。这仍然可以通过获取?
【问题讨论】:
您可以更改 URL 中的标识符以允许分隔的 id 列表:
GET /books/1+2
这将使您的 URL 保持美观和整洁,并遵守 REST 的精神,其中 URL 标识资源。另一个好处是你可以有一个单一的绑定来处理 URL 中任意数量的 id。
@GET
@Produces("application/json")
@Path("/books/{ids}")
public Books getBooks(@PathParam("ids") String ids) {
Books books = new Books();
for (String id: ids.split("+")) {
books.add(bookRepository.findById(id))
}
return books;
}
此方法可以处理多种场景:
GET /books/1
GET /books/2
GET /books/1+2
GET /books/1+2+3
【讨论】:
我们可以讨论两种查询
服务器构造的简单查询
这些查询由服务器构造并传递给 URI,因此客户端与它们无关,因为它从不解析 URI。 (REST 客户端跟踪链接并使用链接的语义注释,例如链接关系来决定选择哪个链接。- HATEOAS 约束)因此您可以使用任何您想要的解决方案,对于如何构建 URI 没有任何限制。 (URI 必须标识资源,因此一个 URI 不能属于多个资源。URI 映射到资源而不是操作,因此如果您想要人类可读的 URI,那么它们可能只包含名词而不包含动词。)
客户端构建的临时查询
通过这种查询,您必须使用 URI 模板并使用一些语义注释参数(可能通过使用依赖于应用程序的词汇)。如果您超出了 URI 模板的能力,那么您需要标准查询语言(例如 SQL)和查询约束的标准描述格式(目前不可用 afaik,但可以是带有 RDF 语义注释的扩展模板语言)。
在您的情况下,不清楚您想要什么。有一点是肯定的,它是由服务器构造的一个简单查询。
您正在谈论用 2 个参数标识的单本书。在这种情况下,结果将包含单个项目资源的表示,您可以有如下内容:/books/x:1+y:2 或 /books/x:1/y:2 或 /books?x=1&y=2。但是用 2 个参数来识别一本书对我来说没有意义。
如果您想在响应中获取多本书,那么我们正在讨论减少集合资源的地图。您可以使用与单个项目资源提到的相同的 URI:/books/x:1+y:2 或 /books/x:1/y:2 或 /books?x=1&y=2。
您可以有一个关于如何区分集合和项目的约定,例如/books?x=1&y=2 可以表示减少集合的映射,/books/x:1+y:2 可以表示识别单个项目。但这部分取决于你。 Ofc 最好对此有一个约定,因为在服务器上编写 URI 生成和路由逻辑更容易。
【讨论】:
没关系。我用以下代码找到了答案:
@GET
@Produces("application/json")
@Path("/network/{id: [0-9]+}/{nid}")
public User getUserByNetworkId(@PathParam("id") int id, @PathParam("nid") String networkId) {
Query q = em.createQuery("SELECT u FROM User u WHERE u.networkId = :id AND u.networkUserId = :nid");
q.setParameter("id", id);
q.setParameter("nid", networkId);
return (User) q.getSingleResult();
}
【讨论】:
常见的方法是将参数作为查询字符串参数传递...但您可以将它们作为 url 的一部分传入。
例如书籍/搜索/arg1/arg2
我个人更喜欢查询字符串的方法。
【讨论】: