Skip to content

Instantly share code, notes, and snippets.

@sam
Last active December 24, 2015 14:59
Show Gist options
  • Save sam/6817248 to your computer and use it in GitHub Desktop.
Save sam/6817248 to your computer and use it in GitHub Desktop.
Write your Models directly to Actions in Play. Add these implicits to your base Controller, import your spray JsonFormats, and now you can just call BLL methods that return the appropriate types.
object Users extends Controller with JsResultConversions with JsFormats {
def show(id) = Action.async {
api.users.get(id)
}
def update = Action.async {
editForm.fold(_ => Future.successful(BadRequest), api.users.save(_))
}
def delete(id) = Action.async {
api.users.delete(id)
}
}
trait JsResultConversions {
implicit def writeableOf_sprayJsValue[T](implicit codec: Codec, ev: RootJsonFormat[T]): Writeable[T] = {
Writeable { value:T =>
// HACK: IntelliJ doesn't pick up the Codec.encode function for some reason.
// (It's a function assigned to a val, not a def.)
// So it highlights this whole block as bad when calling it directly.
// As a workaround I'm giving it an explicitly typed reference in scope
// before I call it.
val encoder: String => Array[Byte] = codec.encode
encoder(ev.write(value).compactPrint)
}(ContentTypeOf[T](Some(ContentTypes.JSON)))
}
implicit def simpleResultOf_futureOptionJsValue[T:RootJsonFormat](result: Future[Option[T]]): Future[SimpleResult] = {
result map {
case Some(value) => Ok(value)
case None => NotFound
}
}
implicit def simpleResultOf_futureTryJsValue[T:RootJsonFormat](result: Future[Try[T]]): Future[SimpleResult] = {
result map {
case Success(value) => Ok(value)
case Failure(e) => BadRequest
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment