I'm still pretty new to Scala and arrived at some kind of typing-roadblock.
Non-SQL databases such as mongo and rethinkdb do not enforce any scheme for their tables and manage data in json format. I've been struggling to get the java API for rethinkdb to work on Scala and there seems to be surprisingly low information on how to actually use the results returned from the database.
Assuming a simple document schema such as this:
{
"name": "melvin",
"age": 42,
"tags": ["solution"]
}
I fail to get how to actually this data in Scala. After running a query, for example, by running something like r.table("test").run(connection), I receive an object from which I can iterate AnyRef objects. In the python word, this most likely would be a simple dict. How do I convey the structure of this data to Scala, so I can use it in code (e.g., query fields of the returned documents)?
From a quick scan of the docs and code, the Java Rethink client uses Jackson to handle deserialization of the JSON received from the DB into JVM objects. Since by definition every JSON object received is going to be deserializable into a JSON AST (Abstract Syntax Tree: a representation in plain Scala objects of the structure of a JSON document), you could implement a custom Jackson
ObjectMapperwhich, instead of doing the usual Jackson magic with reflection, always deserializes into the JSON AST.For example, Play JSON defers the actual serialization/deserialization to/from JSON to Jackson: it installs a module into a vanilla
ObjectMapperwhich specially takes care of instances ofJsValue, which is the root type of Play JSON's AST. Then something like this should work:run(connection)returns aResult[AnyRef]in Scala notation. There's an alternative version,run(connection, typeRef), where the second argument specifies a result type; this is passed to theObjectMapperto ensure that every document will either fail to deserialize or be an instance of that result type:You can then get the next element from the result as a
JsValueand use the usual Play JSON machinery to convert theJsValueinto your domain type:There's some ability with enrichments to improve the Scala API to make a lot of this machinery more transparent.
You could do similar things with the other Scala JSON ASTs (e.g. Circe, json4s), but might have to implement functionality similar to what Play does with the ObjectMapper yourself.