Complexe RESTful GET查询

时间:2010-12-29 19:18:39

标签: java rest tomcat get uri

我理解如何执行GET http://localhost:8080/rest_mysql/books/1之类的查询并使用ID(在本例中为“1”),但是假设您要搜索包含2个变量而不是1的图书。这仍然是通过GET完成?

4 个答案:

答案 0 :(得分:2)

您可以更改网址中的标识符,以允许定界的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

答案 1 :(得分:2)

我们可以谈论2种查询

  • 服务器构建的简单查询

    这些查询由服务器构造并传递给URI,因此客户端与它们无关,因为它从不解析URI。 (REST客户端遵循链接并使用链接的语义注释,例如链接关系来决定选择哪个链接。 - HATEOAS约束)因此,您可以使用任何您想要的解决方案,对于如何构建URI没有任何限制。 (URI必须标识资源,因此一个URI不能属于多个资源.URI被映射到资源而不是操作,所以如果你想拥有人类可读的URI,那么它们可能只包含名词而不是动词。)

  • 客户端构建的临时查询

    通过这种查询,你必须使用URI模板并用一些语义注释params(可能通过使用依赖于应用程序的词汇)。如果超出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可以表示识别单个项目。但那部分取决于你。最好有一个关于此的约定,因为在服务器上编写URI生成和路由逻辑更容易。

答案 2 :(得分:1)

没关系。我用以下代码找到了答案:

    @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();
    }

答案 3 :(得分:0)

常见的方法是将参数作为查询字符串参数传递...但您可以让它们作为URL的一部分进入。

e.g。书籍/搜索/ ARG1 / ARG2

我个人更喜欢查询字符串方法。