Reputation: 3519
I am developing an app for showing different aspects of cars. The app has a tree-like structure like this:
Country>Manufacturer>Model>Car_subsystem>Part
I want this structure to be reflected in browser's address bar:
http://localhost:9000/Germany/BMW/X6/Body/doors
Currently, I do it with play framework's dynamic routing as below:
GET /:Country controllers.Application.controllerFunction(Country : String)
GET /:Country/:Manufacturer controllers.Application.controllerFunction(Country : String, Manufacturer : String)
etc.
This works, but I don't like passing around 5 or 6 parameters to all my controller functions just for the paths to be shown beautifully! Is there any other way?
Upvotes: 1
Views: 1593
Reputation: 55798
Just use Dynamic parts spanning several /
as described in routing doc
route:
GET /Cars/*path controllers.Application.carResolver(path)
Action (simplest approach)
public static Result carResolver(String path) {
Car car = Car.findByPath(path);
return ok(carView.render(car));
}
so each car should have its field path
filled with unique string ID, ie: Germany/BMW/X6
, Germany/Mercedes/ASL` etc.
Of course it will be much better if you split the path
arg by the slash first so you can use each part for displaying different views, 'translate' strings to real object ID etc etc.
public static Result carResolver(String path) {
String[] parts = path.split("/");
int partsLength = parts.length;
String country = (partsLength > 0) ? parts[0] : null;
String manufacturer = (partsLength > 1) ? parts[1] : null;
String carModel = (partsLength > 2) ? parts[2] : null;
// etc
switch (partsLength){
case 0: return countrySelect();
case 1: return allManufacturersIn(country);
case 2: return allModelsOf(manufacturer);
case 3: return singleViewFor(carModel);
// etc
}
return notFound("Didn't find anything for required path...");
}
TIP: "translating" strings to objects will require from you searching in DB by some field, so there's some advices:
Country
should have unique name
as probably you don't want to have Germany 1, Germany 2 etc.This approach requires probably more time than searching by numeric ID's so try to cache somehow (mem-cache OR at least dedicated DB table) the result of resolving ie.:
Germany/BMW/X6 = Country: 1, Manufacturer: 2, CarModel: 3, action: "singleViewFor"
Upvotes: 4