4

I am using play2.1 and I need a validator which checks if a given name is already taken or not in MongoDB. I am using reactive mongo which is an asynchronous MongoDB driver, although my question doesn't depend on this library.

Generally speaking, I would like to know what is the recommended approach of using asynchronous validation with play framework and scala?

Here is my code which I don't think is an elegant way of solving asynchronous validation:

Reads.verifying[String]{name=>
 Await.result(coll.find(Json.obj("name"->name)).one[JsObject].map(_.isEmpty),Duration(1, SECONDS))
}

same pattern when using Reads[T] to validate a JsValue

notTaken=new Reads[JsValue]{
 def reads(js:JsValue):JsResult[JsValue]={
   val oid = js \ "_id"
   Await.result(coll.find(Json.obj("_id"->oid)).one[JsObject].map(_.isEmpty),Duration(1, SECONDS)) match {
     case true => JsSuccess(js)
     case false => JsError("Object Id doesn't exist:"+Json.stringify(oid))
   }
 }

This code works but it doesn't look elegant/scalaish. Any alternative approaches to solve the above cases.

Ali Salehi
  • 6,899
  • 11
  • 49
  • 75
  • I'd the same proble when cheking user existance. http://stackoverflow.com/questions/21709112/scala-async-callback-code-rewriting – sh1ng Sep 29 '14 at 13:17

1 Answers1

0

Await blocks the request thread, if you are ok with that (and configure play accordingly) then your solution is ok, but it would probably not be considered best practice.

I would move that kind of validation into your controller logic and make that action async, think of it more as business logic than vailidation since it interacts with your database.

johanandren
  • 11,249
  • 1
  • 25
  • 30
  • I would like to know, is there a way to rewrite above code in a true asynchronous way. Play actions are 100% asynchronous, so there should be a way to have asynchronous validation. – Ali Salehi Sep 07 '13 at 04:34
  • The way to do it in a 'true asynchronous way' is to move the async parts to the controllers the way the JSON API looks now. – johanandren Sep 09 '13 at 12:07