Complexe RESTful GET queries
I understand how to do queries like GET http://localhost:8080/rest_mys开发者_如何转开发ql/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?
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
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.
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();
}
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.
精彩评论