Adas
Adas

Reputation: 345

Parsing HTTP request JSON body in scala with play

I am using Scala with Play and looking for a cleaner way to write POST request handler below:

  def create = Action.async { request => {
    request.body.asJson match {
      case Some(x) => x.validate[UserDto] match {
        case c: JsSuccess[UserDto] => doActualWork(c.get)
        case e: JsError => Future.successful(BadRequest(""))
      }
      case None => Future.successful(BadRequest(""))
    }
  }
  }

Problems:

  1. Many lines required for only parsing JSON object UserDto (which is a common procedure)
  2. Highly nested (poor readability)

Upvotes: 1

Views: 2765

Answers (2)

Nagarjuna Pamu
Nagarjuna Pamu

Reputation: 14825

Use json body parser. Now body of the request contains json automatically and you can get rid of outer pattern match.

def create = Action.async(parse.json) {
    _.body.validate[UserDto] match {
      case JsSuccess(value, _) => doActualWork(value)
      case _ => Future.successful(BadRequest("bad json body"))
    }
  }

It is advisable to say what went wrong here instead of saying bad json body

Upvotes: 1

Anton Sarov
Anton Sarov

Reputation: 3748

The cleaner way would involve using a Play body parser.

def create = Action.async(parse.json[UserDto]) { request =>
  doActualWork(request.body)
}

The json body parser will validate that the request has a Content-Type of application/json, and send back a 415 Unsupported Media Type response if the request doesn’t meet that expectation. Hence you don’t need to check again in your action code.

Note: if your client is not sending the Content-Type you might try using:

parse.tolerantJson - this is a bit more relaxed


This works because the Action trait is actually defined as:

trait Action[A] extends (Request[A] => Result) {
  def parser: BodyParser[A]
}

Upvotes: 3

Related Questions