Community contributed extensions

Writing Play controllers in Scala

Play controllers are the most important part of any Play applications. A Play Scala application share the same concepts than a classical Play application but use a more functional way to describe actions.

Scala controllers are Objects

A Controller is a Scala singleton object, hosted by the controllers package, and subclassing play.mvc.Controller. In Scala you can declare as many controllers you want in the same file.

This a classical controller definition:

package controllers {
    import play._
    import play.mvc._
    object Users extends Controller {
        def show(id:Long) = Template("user" -> User.findById(id))
        def edit(id:Long, email:String) = {
            User.changeEmail(id, email)

Because Scala provides the native notion of Singleton objects we don’t need anymore to deal with Java static methods while keeping to ability to reference statically any action like show(id).

Action methods return values

A Play controller usually uses imperative orders like render(…) or forbidden() to trigger the response generation. On the contrary an action methods written in Scala is seen as functions and must return a value. This value will be used by the framework to generate the HTTP response resulting of the request.

An action method can of course return several kind of values depending of the request (like for example a Template or an Forbidden value).

Here are listed the typical return types:


Returning the Ok value will generate an empty 200 OK response.

def index = Ok


If an action method return a Template value, the corresponding action template will be rendered, and a 200 OK response filled with the generated content will be sent to the client.

def index = Template

By default the template name will be resolved from the action method name. So if the controllers.Application.index method returns a Template, the app/views/Application/index.html template will be rendered.

You can of course specify another template name:

def index = Template("Commons/home.html")

In this case the app/views/Commons/home.html template will be rendered.

You can also pass values to be included during the template evaluation. Values are passed in form of (Symbol,Any) tuples, where the first member will be used as variable name in the template, and the second member as variable value.

def index = Template('now -> new Date(), 'numbers -> List(1,2,3))

In a Java controller you never specify the template variable name, and Play automatically determine it by extracting the Java variable local name.

It would be to complex to achieve the same thing in Scala without limiting the expressivness of your Scala code (that can contains pattern matching, lambda, etc…). Moreover because we use Tuple definitions here, the result is not so verbose.


Returning an Html value will generated a 200 OK response filled with the HTML content. The response content type will be automatically set to text/html.

def index = Html("<h1>Hello world!</h1>")


Returning an Xml value will generated a 200 OK response filled with the XML content. The response content type will be automatically set to text/xml.

def index = Xml(<message>Hello world!</message>)


Returning an Text value will generated a 200 OK response filled with the text content. The response content type will be automatically set to text/plain.

def index = Text("Hello world!")


Returning an Json value will generated a 200 OK response filled with the text content. The response content type will be automatically set to application/json.

def index = Json("{message: 'Hello world'}")

You can also try to pass any Scala object and Play will try to serialize it to JSON:

def index = Json(users)

However currently the JSON serialization mechanism comes from Java and can not work as exepected with complex Scala structures.

A workaround is to use a Scala dedicated JSON serialization library, for example Lift JSON, and use it as Json(JsonAST.render(users))


Returning the Created value will generate an empty 201 Created response.

def index = Created


Returning the Accepted value will generate an empty 202 Accepted response.

def index = Accepted


Returning the NoContent value will generate an empty 204 No Content response.

def index = NoContent


If an action method return a Action value, Play will redirect the Browser to the corresponding action, using the action method arguments to properly resolve the proper URL.

def index = Action(show(3))

Note that here show(3) is a by-name parameter, and the corresponding methid will not been invoked. Play will resolve this call as an URL (typically something like users/3), and will issue an HTTP redirect to this URL. The action will then be invoked in a new request context.

In a Java controller you achieve the same result by calling directly the corresponding action method. Using Scala call by name concept allow to keep the compiler checked and typesafe redirection without any language hack.


Returning the Redirect value will generate an empty 301 Moved Permanently response.

def index = Redirect("")

You can optionnaly specify a second argument to switch between 301 and 302 response status code.

def index = Redirect("", false)


Returning the NotModified value will generate an empty 304 Not Modified response.

def index = NotModified

You can also specify an ETag to the response:

def index = NotModified("123456")


Returning the BadRequest value will generate an empty 400 Bad Request response.

def index = BadRequest


Returning the Unauthorized value will generate an empty 401 Unauthorized response.

def index = Unauthorized

You can optionnaly specify a realm name:

def index = Unauthorized("Administration area")


Returning the Forbidden value will generate an empty 403 Forbidden response.

def index = Forbidden

You can optionnaly specify an error message:

def index = Forbidden("Unsufficient permissions")


Returning the NotFound value will generate an empty 404 Not Found response.

def index = NotFound

You can optionnaly specify a resource name:

def index = NotFound("Article not found")

Or use a more classical HTTP method, resource Path combination:

def index = NotFound("GET", "/toto")


Returning the Error value will generate an empty 500 Internal Server Error response.

def index = Error

You can optionnaly specify an error message:

def index = Error("Oops…")

Or specify a more specific error code:

def index = Error(503, "Not ready yet…")

Return type inference

You can also directly use the inferred return type to send the action result. For example using a String:

def index = "<h1>Hello world</h1>"

Or you can even use the built-in XML support to write XHTML in a literal way:

def index = <h1>Hello world</h1>

If the return type looks like a binary stream, play will automatically render the response as binary. So generating a captcha image using the built-in Captcha helper can be written as:

def index = Images.captcha

Controller interceptors

Controller interceptors work almost the same way than for Java controller. You simply have to annotate any controller method with the corresponding interceptor annotation:

@Before def logRequests {
    println("New request…")

You see that here, the logRequests method does not return any value. So the request execution will continue by invoking the next interceptors and eventually the action method.

But you can also write some interceptor that return a value:

@Before def protectActions = {

Here the execution will stop, and the Forbidden value will be used to generate the HTTP response.

If you want to continue the request execution, just make your interceptor return Continue:

@Before def protectActions = {
    session("isAdmin") match {
        case Some("yes") => Continue
        case _ => Forbidden("Restricted to administrators")

Mixing controllers using Traits

Scala Traits can be used to compose controller more effeciently by mixing several aspects. You can define both action methods and interceptors in a controller Trait.

For example the following Secure trait add a seucrity interceptor to any controller applying the Trait:

trait Secure {
    self:Controller =>
    @Before checkSecurity = {
        session("username") match {
            case Some(username) => renderArgs += "user" -> User(username)
            case None => Action(Authentication.login)
    def connectedUser = renderArgs("user").get

Note that here we use the self:Controller => notation to indicate that this Trait can only be mixed with a Controller type.

And you can use it to create a secured controller:

object Application extends Controller with Secure {
    def index = <h1>Hello {}!</h1>

There is also small differences about Data binding