Using POST routes parameters in Play Framework

Mattias picture Mattias · Nov 26, 2013 · Viewed 15.7k times · Source

I have a login route that should transmit its input parameters as POST variables. I have defined my route like this:

POST    /v1/accounts/login          controllers.v1.Accounts.login(username: String, password: String)

and my Controller is like this:

object Accounts extends Controller {
  def login(username: String, password: String) = Action {
    Ok("Foo " + username)
  }
}

When I test this route using Chromes Advance REST Client it only works for GET parameters and not if I send it as application/x-www-form-urlencoded POST form data.

The Play Framework documentation never actually mentions POST parameters but neither does it say that it does not work.

I think it might get it to work if I create a Form and bind my request to that but that seems needlessly complex.

Is there really no way to bind POST parameters using the routes file?

Answer

biesior picture biesior · Nov 26, 2013

Route = resolving params inside the URL = sending params via GET.

That means, that you are trying to send POST request by... GET params... where's the sense ?

James Roper explains that:

At routing time, Play hasn't yet consumed the request body, and so hasn't parsed the submitted form. - and you don't want it to either, because it's your action that decides how/whether the request body gets parsed, streamed, sent elsewhere, if Play did this at routing time, it would limit what you could do in an action.

From security point of view it's definitely bad idea to leave credentials in logs of every machine in the path of client.

Instead you should do it with common form handling way like described in base form documentation:

route:

POST    /v1/accounts/login      controllers.v1.Accounts.login

action:

val userForm = Form(
  tuple(
    "username" -> text,
    "password" -> text
  )
)

def login = Action { implicit request =>
  val (username, password) = userForm.bindFromRequest.get
  Ok("Hello " + username + ", you're trying to login with: " + password)
}