Play + scala + reactive mongo

16
Play + Scala + Reactive Mongo Building a “reactive” data-access layer to mongoDB

description

Meetup presentation. Covers building a non-blocking asynchronous data-access layer using Scala, Play framework, MongoDB and the Reactive Mongo Driver

Transcript of Play + scala + reactive mongo

Page 1: Play + scala + reactive mongo

Play + Scala + Reactive Mongo

Building a “reactive” data-access layer to mongoDB

Page 2: Play + scala + reactive mongo

About Us

Max Kremer

Trialfire - co-founderfounded in June 2013

Autodesk - cloud solutions architect

Datastay - co-founderAcquired by Autodesk 2011

Marconi Lanna

Trialfire - lead developerfounded in June 2013

Too many startups since 1996 to list here

Page 3: Play + scala + reactive mongo

Why “reactive”

Classic Synchronous Model:

With a traditional synchronous database driver, each operation blocks the current thread until a response is received.

More requests = more threads waiting = poor scalability

Page 4: Play + scala + reactive mongo

What is “reactive”

Fully non-blocking and asynchronous I/O operations

Page 5: Play + scala + reactive mongo

Play and async I/O

• Java NIO• Non-blocking, asynchronous IO• Process multiple HTTP requests with a single thread• Large number of concurrent requests can be handled

with a few threads

Page 6: Play + scala + reactive mongo

Example

• A Play controller using a Future result:package controllers

import play.api.mvc.{Action, Controller}import concurrent.{ExecutionContext, Future}import ExecutionContext.Implicits.global

object StuffController extends Controller {def doStuff( ) = Action {

val someStuff = scala.concurrent.future {models.Stuff.fetch( )}Async {someStuff.map(value => Ok(value))}}}   

Page 7: Play + scala + reactive mongo

A word about Futures

• Represents a value that will be available later• Execution contexts - think “thread pools”• Futures are Monads• Layer of abstraction over multi-threading

Page 8: Play + scala + reactive mongo

Data Access Layer

• Active Record Design Pattern• Based on Futures• Model = Case Class + Companion Object• Stackable Traits

Page 9: Play + scala + reactive mongo

Persistence using Traitsimport play.api.libs.json.Json

case class User( id       : Option[BSONObjectID], firstName: String, lastName : String, email    : String, password : String)

object User extends DataAccess[User] {    def collectionName = “user”    implicit val format = Json.format[User]}

Page 10: Play + scala + reactive mongo

The Data Access Trait

trait DataAccess[M] {    def collectionName: Stringimplicit val format: Format[M]

private def db = ReactiveMongoPlugin.dbprivate def collection = db[JSONCollection](collectionName)

    def insert(instance: M): (BSONObjectID, Future[LastError]) = {     val id = BSONObjectID.generate       (id, collection.insert(Json.toJson(instance) ++ id))   }

Page 11: Play + scala + reactive mongo

The Data Access Trait (cont’d)

def update(instance: M): Future[LastError] = {instance.id map { id =>collection.update(id, Json.toJson(instance))} getOrElse Future.successful(LastError(err = Some("Invalid ID"))}

def byId(id: BSONObjectID): Future[Option[M]] = {    collection.find(id).cursor.headOption map { _ flatMap { doc: JsObject =>        doc.asOpt[M] } }}

Page 12: Play + scala + reactive mongo

Pros

• easy compared to sql• no schemas• no queries• no migration• it just works

conversion from/to json automatically handled by play json api macros

Page 13: Play + scala + reactive mongo

Cons

• Futures all the way down…• Futures all the way up, too...• No joins

Page 14: Play + scala + reactive mongo

Cons (cont’d)case class Book( name  : String    , author: Author)

case class author(name: String) {    lazy val books: Seq[Book] = Book.byAuthor(this)}

lazy val books: Future[Seq[Book]] = Book.byAuthor(this)

val books = author.books

author.books map { books =>...}

Page 15: Play + scala + reactive mongo

Links

reactive mongo driver: http://reactivemongo.org/

Play ReactiveMongo plugin: https://github.com/ReactiveMongo/Play-eactiveMongo

Page 16: Play + scala + reactive mongo

The End

Thanks for listening

Future[Option[Applause]]

[email protected] [email protected]

We’re hiring!