is there a good or proper way to render the output in Play Framework depending on a parameter? Example:
For HTML:
http://lo
If /user/5?v=html
and /user/5?v=json
return two representations of the same resource, they should be the same URL, e.g. /user/5
, according to the REST principles.
On client side, you can use the Accept
header in your requests to indicate which representation you want the server to send you.
On server side, you can write the following with Play 2.1 to test the value of the Accept
header:
public static Result user(Long id) {
User user = User.find.byId(id);
if (user == null) {
return notFound();
}
if (request().accepts("text/html")) {
return ok(views.html.user(user));
} else if (request().accepts("application/json")) {
return ok(Json.toJson(user));
} else {
return badRequest();
}
}
Note that the test against "text/html"
should always be written prior to any other content type because browsers set the Accept
header of their requests to */*
which matches all types.
If you don’t want to write the if (request().accepts(…))
in each action you can factor it out, e.g. like the following:
public static Result user(Long id) {
User user = User.find.byId(id);
return representation(user, views.html.user.ref);
}
public static Result users() {
List users = User.find.all();
return representation(users, views.html.users.ref);
}
private Result representation(T resource, Template1 html) {
if (resource == null) {
return notFound();
}
if (request().accepts("text/html")) {
return ok(html.apply(resource));
} else if (request().accepts("application/json")) {
return ok(Json.toJson(resource));
} else {
return badRequest();
}
}