You are viewing the documentation for the 2.6.x release series. The latest stable release series is 3.0.x.

§Custom Routing

Play provides a mechanism to bind types from path or query string parameters.


PathBindable allows to bind business objects from the URL path; this means we’ll be able to define routes like /user/3 to call an action such as the following:


public Result user(User user) {
  return ok(;

The user parameter will automatically be retrieved using the id extracted from the URL path, e.g. with the following route definition:


GET     /user/:user            controllers.BinderApplication.user(user: javaguide.binder.models.User)

Any type T that implements PathBindable can be bound to/from a path parameter.
It defines abstract methods bind (build a value from the path) and unbind (build a path fragment from a value).

For a class like:

public class User implements PathBindable<User> {

  public Long id;
  public String name;

A simple example of the binder’s use binding the :id path parameter:

public User bind(String key, String id) {

  // findById meant to be lightweight operation
  User user = findById(new Long(id));
  if (user == null) {
    throw new IllegalArgumentException("User with id " + id + " not found");
  return user;

public String unbind(String key) {
  return String.valueOf(id);

In this example findById method is invoked to retrieve User instance.

Note: in a real application such method should be lightweight and not involve e.g. DB access, because the code is called on the server IO thread and must be totally non-blocking. You would therefore for example use simple objects identifier as path bindable, and retrieve the real values using action composition.


A similar mechanism is used for query string parameters; a route like /age can be defined to call an action such as:


public Result age(AgeRange ageRange) {
  return ok(String.valueOf(ageRange.from));

The age parameter will automatically be retrieved using parameters extracted from the query string e.g. /age?from=1&to=10

Any type T that implements QueryStringBindable can be bound to/from query one or more query string parameters. Similar to PathBindable, it defines abstract methods bind and unbind.

For a class like:

public class AgeRange implements QueryStringBindable<AgeRange> {

  public Integer from;
  public Integer to;

A simple example of the binder’s use binding the :from and :to query string parameters:

public Optional<AgeRange> bind(String key, Map<String, String[]> data) {

  try {
    from = new Integer(data.get("from")[0]);
    to = new Integer(data.get("to")[0]);
    return Optional.of(this);

  } catch (Exception e) { // no parameter match return None
    return Optional.empty();

public String unbind(String key) {
  return new StringBuilder().append("from=").append(from).append("&to=").append(to).toString();

Next: Extending Play

Found an error in this documentation? The source code for this page can be found here. After reading the documentation guidelines, please feel free to contribute a pull request. Have questions or advice to share? Go to our community forums to start a conversation with the community.