复杂的 RESTful GET 查询

发布于 2024-10-09 18:49:50 字数 200 浏览 8 评论 0原文

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

I understand how to do queries like GET http://localhost:8080/rest_mysql/books/1 and pull with an ID, in this case "1", but lets say you wanted to search for a book with 2 variablies instead of 1. Can this still be done via GET?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

瑕疵 2024-10-16 18:49:50

您可以更改 URL 中的标识符以允许使用分隔的 ids 列表:

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

You could change the identifier in your URL to allow a delimited list of ids:

GET /books/1+2

This would keep your URL nice and neat, and adhere to the spirit of REST, wherein the URL identifies a resource. Another benefit is that you could have a single binding which would handle an arbitrary number of ids in the URL.

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

This method could handle multiple scenarios:

GET /books/1
GET /books/2
GET /books/1+2
GET /books/1+2+3
紙鸢 2024-10-16 18:49:50

我们可以讨论两种查询

  • 服务器构造的简单查询

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

  • 由客户端构建的临时查询

    通过这种查询,您必须使用 URI 模板并使用一些语义注释参数(可能通过使用依赖于应用程序的词汇)。如果你超出了URI模板的能力,那么你需要一个标准的查询语言(例如SQL)和一个标准的查询约束描述格式(据我所知目前还没有,但可以是用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 生成和路由逻辑更容易。

We can talk about 2 kind of queries

  • simple queries constructed by the server

    These queries are constructed by the server and passed to the URI, so the client has nothing to do with them, because it never parses the URIs. (REST clients follow links and use semantic annotations of links, for example link relations to decide what link to choose. - HATEOAS constraint) So you can use any solution you want, there are no constraints about how to build an URI. (URIs have to identify resources, so one URI cannot belong to multiple resources. URIs are mapped to resources and not operations, so if you want to have human readable URIs, then they will probably contain only nouns and not verbs.)

  • ad-hoc queries constructed by the client

    By this kind of queries you have to use URI templates and annotate the params with some semantics (probably by using an application dependent vocab). If you exceed the capabilities of URI templates, then you need a standard query language (e.g. SQL) and a standard description format for your query constraints (currently not available afaik, but can be an extended template language annotated with RDF semantics).

In your case it is not clear what you want. One thing is sure, it is a simple query constructed by the server.

  • You are talking about a single book identified with 2 parameters. In this case the result will contain the representation of a single item resource and you can have something like this: /books/x:1+y:2 or /books/x:1/y:2 or /books?x=1&y=2. But identifying a book with 2 params does not make sense to me.

  • If you want to get multiple books in the response, then we are talking about map reducing a collection resource. You can use just the same URIs as mentioned by the single item resource: /books/x:1+y:2 or /books/x:1/y:2 or /books?x=1&y=2.

You can have a convention about how to distinguish collections and items, for example /books?x=1&y=2 can mean map reducing a collection and /books/x:1+y:2 can mean identifying a single item. But that part depends on you. Ofc it is better to have a convention about this, because it is easier to write the URI generation and routing logic on the server.

随遇而安 2024-10-16 18:49:50

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

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

Nevermind. I found my answer with the folliwing code:

    @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();
    }
梦与时光遇 2024-10-16 18:49:50

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

例如 books/search/arg1/arg2

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

Common approach is to pass the arguments as query string parameters... but you could have them come in as part of the url instead.

e.g. books/search/arg1/arg2

Personally I prefer the query string approach.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文