I'm working on a Scala project that uses DynamoDB for persistence, and does this by modelling the records as case classes.
This is becoming increasingly more relational, which means we have classes like this:
UserRecord(
id="1",
name="Matt",
friendIds=Seq("2", "3")
)
which are then converted into a business object by making some extra database calls, to produce something that looks like this:
User(
id="1",
name="Matt",
friends=Seq(
User(id="2", ...),
User(id="3", ...)
)
)
The rest of the code then deals with the User
and not the UserRecord
.
This is problematic for a few reasons:
- Not all code paths actually require the User objects in the
friends
list, so it's a waste of time and database capacity to do the reads every time - It doesn't work with recursive structures (if two users were friends then this would go on making requests forever)
One idea I had was to make relationships lazy futures, so that extra database calls are only made when they are accessed, but not sure this is idiomatic as it seems to be introducing a lot of complexity to our plain case classes that are currently very easy to use.
Is there a general approach to solving this sort of problem in functional languages, or even Scala specifically?
(related question, which has an interesting set of answers but didn't really address this problem: Why would I not need an ORM in a functional language like Scala?)