

§Body parsers

§What is a body parser?

An HTTP PUT or POST request contains a body. This body can use any format, specified in the Content-Type request header. In Play, a body parser transforms this request body into a Scala value.

However the request body for an HTTP request can be very large and a body parser can’t just wait and load the whole data set into memory before parsing it. A BodyParser[A] is basically an Iteratee[Array[Byte],A], meaning that it receives chunks of bytes (as long as the web browser uploads some data) and computes a value of type A as result.

Let’s consider some examples.

Additionally a body parser has access to the HTTP request headers before it starts parsing the request body, and has the opportunity to run some precondition checks. For example, a body parser can check that some HTTP headers are properly set, or that the user trying to upload a large file has the permission to do so.

Note: That’s why a body parser is not really an Iteratee[Array[Byte],A] but more precisely a Iteratee[Array[Byte],Either[Result,A]], meaning that it has the opportunity to send directly an HTTP result itself (typically 400 BAD_REQUEST, 412 PRECONDITION_FAILED or 413 REQUEST_ENTITY_TOO_LARGE) if it decides that it is not able to compute a correct value for the request body

Once the body parser finishes its job and gives back a value of type A, the corresponding Action function is executed and the computed body value is passed into the request.

§More about Actions


  def parser: BodyParser[A]


trait Request[+A] extends RequestHeader {
  def body: A



§Default body parser: AnyContent

In our previous examples we never specified a body parser. So how can it work? If you don’t specify your own body parser, Play will use the default, which processes the body as an instance of play.api.mvc.AnyContent.

This body parser checks the Content-Type header and decides what kind of body to process:

For example:

def save = Action { request =>
  val body: AnyContent = request.body
  val textBody: Option[String] = body.asText

  // Expecting text body { text =>
    Ok("Got: " + text)
  }.getOrElse {
    BadRequest("Expecting text/plain request body")

§Specifying a body parser

The body parsers available in Play are defined in play.api.mvc.BodyParsers.parse.

So for example, to define an action expecting a text body (as in the previous example):

def save = Action(parse.text) { request =>
  Ok("Got: " + request.body)

Do you see how the code is simpler? This is because the parse.text body parser already sent a 400 BAD_REQUEST response if something went wrong. We don’t have to check again in our action code, and we can safely assume that request.body contains the valid String body.

Alternatively we can use:

def save = Action(parse.tolerantText) { request =>
  Ok("Got: " + request.body)

This one doesn’t check the Content-Type header and always loads the request body as a String.

Tip: There is a tolerant fashion provided for all body parsers included in Play.


  Ok("Saved the request content to " + request.body)

§Combining body parsers

In the previous example, all request bodies are stored in the same file. This is a bit problematic isn’t it? Let’s write another custom body parser that extract the user name from the request Session, to give a unique file for each user:

val storeInUserFile = parse.using { request =>
  request.session.get("username").map { user =>
  }.getOrElse {

def save = Action(storeInUserFile) { request =>
  Ok("Saved the request content to " + request.body)


§Max content length

Text based body parsers (such as text, json, xml or formUrlEncoded) use a maximum content length because they have to load all of the content into memory.

There is a default content length (the default is 100KB), but you can also specify it inline:

// Accept only 10KB of data.
  Ok("Got: " + text)

Tip: The default content size can be defined in application.conf:


You can also wrap any body parser with maxLength:

// Accept only 10KB of data.
  Ok("Saved the request content to " + request.body)

Next: Action composition