开发者

REST URI Design : Optional and multivalue information passing

开发者 https://www.devze.com 2023-03-04 13:31 出处:网络
I have one search widget where people search for car dealers by zip code. There are also some optional checkboxes to refin开发者_JAVA百科e search in that widget.

I have one search widget where people search for car dealers by zip code. There are also some optional checkboxes to refin开发者_JAVA百科e search in that widget.

Here is the URI for searching dealer by zip code.

http://localhost:8080/dealer/zip/10080

If user selects checboxes then the URI will be

http://localhost:8080/dealer/zip/10080servicetype=type1&servicetype=type2&servicetype=type3

I am using jersey. Here is java code.

@Path("/dealer")
@Produces(MediaType.APPLICATION_JSON)
public class DealerLocatorRS {
    private DealerService dealerService=new DealerService();

    @GET
    @Path("/zip/{zip}")
    public List<Dealer> getByZip(@PathParam("zip") String zip, 
        @QueryParam("servicetype") List<String> servicetype){
    .. . ..
    }

Is this right approach to pass optional and multiple values and . Can anybody help me to apply best practices?


I'm not sure that I'd map a search for dealers in a particular zip code to a resource; it doesn't feel quite right. Instead, I'd have a resource that lists all the dealers, with individual dealers being sub-resources of that. If it was possible to return a subset of the list of subresources restricted by properties (e.g., their zip code) then that would be a great way to implement a search, otherwise I'd have a separate search handler that returns a list of links to matching dealer resources.

@Path("/dealer")
public class Dealers {
    @GET
    public List<Dealer> getAll() { ... }
    @GET
    @Path("search/byZip")
    public List<URI> getByZip(@QueryParam("zip") String zip, ...) { ... }
    @Path("{dealerId:[^/]+}")
    public Dealer getDealer(@PathParam("dealerId") String id) { ... }
}


If you are serious about understanding and applying REST, I'd recommend reading the REST paper, if you haven't done so yet.

According to the architecture proposed in that paper, Each URL maps to a resource. A resource could be something extrinsic and tangible, like a car dealership. Or it could be something "virtual" like a "region", or even a zipcode that might contain dealerships.

As to how you parameterize queries, think about what resource you want to use to satisfy or expose the queries. Why would you treat "zipcode" as a variable parameter, any differently than, say your "servicetype"? Are they not both qualifiers to select a subset of dealerships? Think about why you are making them different - there may be a good reason.

For example, you could do:

  • http://server/dealer/zip/10070
    list all dealers in 10070

  • http://server/dealer/service/transmissions
    list all dealers that do transmission work

  • http://server/dealer/service/transmissions/zip/10070
    list all dealers that do transmission work in zip 10070

  • http://server/dealer/zip/10070/service/transmissions
    list all dealers in zip 10070 that do transmission work

  • http://server/dealer/service/transmissions/service/lighttrucks
    list all dealers that do transmission work and do light truck service

Think about the mapping of URLs to resources. It may be that two distinct URLs map to the same "result". you need to decide whether that's appropriate for you.

It's also perfectly fine to retrieve a resource and then do queries on it on the client side. Not all work need be done by the server. You could search through the results obtained by http://server/dealer/zip/10070 on the client side, to find the ones that supply the desired services. This may or may not be a performance win, depending on the size of the data transmitted and the frequency and variety of queries.

Supposing an overall result set of 10 (say, ten dealers within a zipcode), a Javascript foreach loop searching for a dealer that offers service X is going to be faster than an additional AJAX call asking the server to do that query on behalf of the client.


This is ok, unless your URL becomes too long (although URL length is not limited by any spec, some browsers and intermediaries limit it, so the best practices to keep it under 1K)

If it becomes too long, you may use POST instead of GET.

P.S. You have bug in your code, it should be @QueryParam("servicetype") List<String> servicetype) to match the example URI.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号