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.