Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subresource and path variable conflicts in REST?

Is it considered bad practice to design a REST API that may have an ambiguity in the path resolution? For example:

GET /animals/{id}   // Returns the animal with the given ID
GET /animals/dogs   // Returns all animals of type dog

Ok, that's contrived, because you would actually just do GET /dogs, but hopefully it illustrates what I mean. From a path resolution standpoint, it seems like you wouldn't know whether you were looking for an animal with id="dogs" or just all the dogs

Specifically, I'm interested in whether Jersey would have any trouble resolving this. What if you knew the id to be an integer?

like image 267
Eric Avatar asked Mar 14 '23 14:03

Eric


1 Answers

"Specifically, I'm interested in whether Jersey would have any trouble resolving this"

No this would not be a problem. If you look at the JAX-RS spec § 3.7.2, you'll see the algorithm for matching requests to resource methods.

[E is the set of matching methods]...

Sort E using the number of literal characters in each member as the primary key (descending order), the number of capturing groups as a secondary key (descending order) and the number of capturing groups with non-default regular expressions (i.e. not ‘([^ /]+?)’) as the tertiary key (descending order)

So basically it's saying that the number of literal characters is the primary key of which to sort by (note that it is short circuiting; you win the primary, you win). So for example if a request goes to /animals/cat, @Path("/animals/dogs") would obviously not be in the set, so we don't need to worry about it. But if the request is to /animals/dogs, then both methods would be in the set. The set is then sorted by the number of literal characters. Since @Path("/animals/dogs") has more literal characters than @Path("/animals/"), the former wins. The capturing group {id} doesn't count towards literal characters.

"What if you knew the id to be an integer?"

The capture group allows for regex. So you can use @Path("/animals/{id: \\d+}"). Anything not numbers will not pass and lead to a 404, unless of course it is /animals/dogs.

like image 110
Paul Samsotha Avatar answered Apr 27 '23 06:04

Paul Samsotha