【问题标题】:Complexe RESTful GET queries复杂的 RESTful GET 查询
【发布时间】:2010-12-29 19:18:39
【问题描述】:

我了解如何执行 GET http://localhost:8080/rest_mysql/books/1 之类的查询并使用 ID(在本例中为“1”)进行查询,但假设您想搜索具有 2 个变量而不是 1 个变量的书。这仍然可以通过获取?

【问题讨论】:

    标签: java rest tomcat get uri


    【解决方案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
    

    【讨论】:

      【解决方案2】:

      我们可以讨论两种查询

      • 服务器构造的简单查询

        这些查询由服务器构造并传递给 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 生成和路由逻辑更容易。

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          【解决方案4】:

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

          例如书籍/搜索/arg1/arg2

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

          【讨论】:

            猜你喜欢
            • 2016-09-07
            • 2014-12-25
            • 2012-12-19
            • 1970-01-01
            • 1970-01-01
            • 2013-06-28
            • 2015-06-17
            • 1970-01-01
            • 2012-07-13
            相关资源
            最近更新 更多