Reputation: 3329
In Play, what is the best way to handle routing of endpoints based on the data type provided?
GET /my/:id controllers.MyController.getById(id: Long)
GET /my/:name controllers.MyController.getByName(name: String)
getById
should be called for GET /my/1
.
getByName
should be called for GET /my/bob
(because bob
does not cast to Long
)
This may not always be the best endpoint design, but if it's required what is the best way to achieve this?
One workaround as noted in this answer is to create single controller methods which try the conversion for you.
GET /my/:arg controllers.MyController.getByAny(arg: String)
Result getByAny(String arg) {
try {
getById( Long.parseLong(arg)) ;
} catch (Exception e) {
return getByName(arg)
}
}
A downside to this is if using Swagger docs you no longer have separate documentation for each route.
You also must do this individually for each conflicting group of routes.
Is there a way to add similar functionality, without breaking documention, to all Endpoints rather than one by one?
Upvotes: 0
Views: 15
Reputation: 1056
Try using custom patterns.
GET /items/$id<[0-9]+> controllers.Items.getById(id: Long)
GET /items/$name<[a-zA-Z]+> controllers.Items.getByName(name)
In fact the second one could probably be simplified to:
GET /items/:name controllers.Items.getByName(name)
When multiple routes match the first one to match should be picked.
Upvotes: 1