dekkar76 / flickr

Transparent Scala case class serialization for MongoDB

Introducing Play Mongo BSON

What we propose today is Play Mongo BSON, a Scala MongoDB Object-Document-Mapper for Play Framework using macros to serialize/deserialize case class as BSON documents.

At Snips, one of our favorite backend stacks is using Scala + Play Framework + MongoDB.

This provides an easy way to kick off backend projects with :

  • RESTful API
  • reactive programming
  • json support
  • flexibility in document storage

Writing custom serializers for case class is boring

We need a MongoDB driver that supports Scala case class serialization/deserialization.

For a long time, we have been using Salat. Salat was good in that it was a “small” library and not a full blown driver, but is ageing bad: it was based on bytecode analysis and bytecode generation whereas Scala compiler macros can be used now (simpler build, no more issues with type elision). Also, it is still bound (by the BSON types) to the “old” synchronous MongoDB API.

Alternative projects are offering full drivers and object-mapping solutions, but now that the official driver is asynchronous, they feel less relevant. Also, they are re-inventing the whole API instead of sticking to the official MongoDB line: same API for all drivers. This is getting frustrating when switching between languages constantly.

How does it work ?

Play bson mongo provides a generator using Scala macros generating codecs for your case class. By using macros, codecs are generated at compile time. No tricky bytecode manipulation or runtime introspection overhead.

You’ll just need to register them in the standard MongoDB driver codec registry. It all takes one single line of code.

Show me the code.

In your build.sbt, you will need :

  • Sonatype resolver
  • Play Mongo BSON library
  • Scala MongoDB driver

Then, define a sample case class defining your MongoDB document.

Next step is to write a DAO which will be responsible for storing and retrieving a case class as a document in MongoDB.

DatabaseContext is used to read your MongoDB configuration (connection url), build MongoDB client and register the codec registry. This object can be easily injected using dependency injection.

BaseDAO provides all methods to retrieve and store.

Final step, calling it !

Final thoughts

In the end, this lightweight library provides a transparent case class serialization compatible with the official Scala MongoDB driver.

Play Mongo BSON is for now in 0.2 as its case class mapping is not fully complete (for instance, we want to add support for default values). It is however reliable and can be used in production. We have been using it extensively in production at Snips for nearly one year.