Handy is a set of classes that make writing apps in a functional style really quite easy.
How easy? Here’s an example. (We’ll make it even easier in a mo.)
val approval = request.approval
for (
text <- Ref((request.body \ "text").asOpt[String]) orIfNone UserError("The message contained no text");
entry <- refContentEntry(entryId);
approved <- approval ask Permissions.CommentOnEntry(entry.itself);
updated <- ContentEntry.addComment(entry, approval.who, text);
j <- updated.toJsonFor(approval)
) yield j
In those few lines, we’ve:
And we’ve done it in an asynchronous non-blocking manner.
If you’re using the Play Framework, then you can also use some code that’s in handy-play and handy-appbase-core.
handy-play adds some code for producing Enumerators that work with Play’s iteratee libraryhandy-appbase-code adds some code for Single Page ApplicationsThis is the example above filled out to use handy-appbase-core to define a Play controller action
def commentOnEntry = DataAction.one(parse.json) { implicit request =>
for (
text <- Ref((request.body \ "text").asOpt[String]) orIfNone UserError("The message contained no text");
entry <- refContentEntry(entryId);
approved <- request.approval ask Permissions.CommentOnEntry(entry.itself);
updated <- ContentEntry.addComment(entry, approval.who, text)
) yield updated
}
Here, we’ve defined a controller action that has some helpful propertes:
Content to JSON using a JSON converter you have defined. That can involve more aysnchronous calls if you wish. (For instance if you want to fetch and embed other items into the response too.)Forbidden if the permission is refused, InternalServerError if there’s an unexpected error, and usually UserError is configured to return BadRequest.Many of my projects use ReactiveMongo as the database driver, so there’s also a couple of classes provided for that.