How do I abstract the domain layer from the persistence layer in Scala - scala

UPDATE:
I've edited the title and added this text to better explain what I'm trying to achieve: I'm trying to create a new application from the ground up, but don't want the business layer to know about the persistence layer, in the same way one would not want the business layer to know about a REST API layer. Below is an example of a persistence layer that I would like to use. I'm looking for good advice on integrating with this i.e. I need help with the design/architecture to cleanly split the responsibilities between business logic and persistence logic. Maybe a concept along the line of marshalling and unmarshalling of persistence objects to domain objects.
From a SLICK (a.k.a. ScalaQuery) test example, this is how you create a many-to-many database relationship. This will create 3 tables: a, b and a_to_b, where a_to_b keeps links of rows in table a and b.
object A extends Table[(Int, String)]("a") {
def id = column[Int]("id", O.PrimaryKey)
def s = column[String]("s")
def * = id ~ s
def bs = AToB.filter(_.aId === id).flatMap(_.bFK)
}
object B extends Table[(Int, String)]("b") {
def id = column[Int]("id", O.PrimaryKey)
def s = column[String]("s")
def * = id ~ s
def as = AToB.filter(_.bId === id).flatMap(_.aFK)
}
object AToB extends Table[(Int, Int)]("a_to_b") {
def aId = column[Int]("a")
def bId = column[Int]("b")
def * = aId ~ bId
def aFK = foreignKey("a_fk", aId, A)(a => a.id)
def bFK = foreignKey("b_fk", bId, B)(b => b.id)
}
(A.ddl ++ B.ddl ++ AToB.ddl).create
A.insertAll(1 -> "a", 2 -> "b", 3 -> "c")
B.insertAll(1 -> "x", 2 -> "y", 3 -> "z")
AToB.insertAll(1 -> 1, 1 -> 2, 2 -> 2, 2 -> 3)
val q1 = for {
a <- A if a.id >= 2
b <- a.bs
} yield (a.s, b.s)
q1.foreach(x => println(" "+x))
assertEquals(Set(("b","y"), ("b","z")), q1.list.toSet)
As my next step, I would like to take this up one level (I still want to use SLICK but wrap it nicely), to working with objects. So in pseudo code it would be great to do something like:
objectOfTypeA.save()
objectOfTypeB.save()
linkAtoB.save(ojectOfTypeA, objectOfTypeB)
Or, something like that. I have my ideas on how I might approach this in Java, but I'm starting to realize that some of my object-oriented ideas from pure OO languages are starting to fail me. Can anyone please give me some pointers as to how approach this problem in Scala.
For example: Do I create simple objects that just wrap or extend the table objects, and then include these (composition) into another class that manages them?
Any ideas, guidance, example (please), that will help me better approach this problem as a designer and coder will be greatly appreciated.

The best idea would be to implement something like data mapper pattern. Which, in contrast to active record, will not violate SRP.
Since I am not a Scala developer, I will not show any code.
The idea is following:
create domain object instance
set conditions on the element (for example setId(42), if you are looking for element by ID)
create data mapper instance
execute fetch() method on the mapper by passing in domain object as parameter
The mapper would look up current parameters of provided domain object and, based on those parameters, retrieve information from storage (which might be SQL database, or JSON file or maybe a remote REST API). If information is retrieved, it assigns the values to the domain object.
Also, I must note, that data mappers are created for work with specific domain object's interface, but the information, which they pass from domain object to storage and back, can be mapped to multiple SQL tables or multiple REST resources.
This way you can easily replace the mapper, when you switch to different storage medium, or even unit-test the logic in domain objects without touching the real storage. Also, if you decide to add caching at some point, that would be just another mapper, which tried to fetch information from cache, and, if it fails, the mapper for persistent storage kicks in.
Domain object (or, in some cases, a collection of domain objects) would be completely unaware of whether it is stored or retrieved. That would be the responsibility of the data mappers.
If this is all in MVC context, then, to fully implement this, you would need another group of structures in the model layer. I call them "services" (please share, of you come up with better name). They are responsible for containing the interaction between data mappers and domain objects. This way you can prevent the business logic from leaking in the presentation layer (controllers, to be exact), and these services create a natural interface for interaction between business (also know as model) layer and the presentation layer.
P.S. Once again, sorry that I cannot provide any code examples, because I am a PHP developer and have no idea how to write code in Scala.
P.P.S. If you are using data mapper pattern, the best option is to write mappers manually and not use any 3rd party ORM, which claims to implement it. It would give you more control over codebase and avoid pointless technical debt [1] [2].

A good solution for simple persistence requirements is the ActiveRecord pattern: http://en.wikipedia.org/wiki/Active_record_pattern . This is implemented in Ruby and in Play! framework 1.2, and you can easily implement it in Scala in a stand-alone application
The only requirement is to have a singleton DB or a singleton service to get a reference to the DB you require. I personally would go for an implementation based on the following:
A generic trait ActiveRecord
A generic typeclass ActiveRecordHandler
Exploiting the power of implicits, you could obtain an amazing syntax:
trait ActiveRecordHandler[T]{
def save(t:T):T
def delete[A<:Serializable](primaryKey:A):Option[T]
def find(query:String):Traversable[T]
}
object ActiveRecordHandler {
// Note that an implicit val inside an object with the same name as the trait
// is one of the way to have the implicit in scope.
implicit val myClassHandler = new ActiveRecordHandler[MyClass] {
def save(myClass:MyClass) = myClass
def delete[A <: Serializable](primaryKey: A) = None
def find(query: String) = List(MyClass("hello"),MyClass("goodbye"))
}
}
trait ActiveRecord[RecordType] {
self:RecordType=>
def save(implicit activeRecordHandler:ActiveRecordHandler[RecordType]):RecordType = activeRecordHandler.save(this)
def delete[A<:Serializable](primaryKey:A)(implicit activeRecordHandler:ActiveRecordHandler[RecordType]):Option[RecordType] = activeRecordHandler.delete(primaryKey)
}
case class MyClass(name:String) extends ActiveRecord[MyClass]
object MyClass {
def main(args:Array[String]) = {
MyClass("10").save
}
}
With such a solution, you only need your class to extends ActiveRecord[T] and have an implicit ActiveRecordHandler[T] to handle this.
There is actually also an implementation: https://github.com/aselab/scala-activerecord which is based on similar idea, but instead of making the ActiveRecord having an abstract type, it declares a generic companion object.
A general but very important comment on the ActiveRecord pattern is that it helps meet simple requirements in terms of persistence, but cannot deal with more complex requirements: for example is when you want to persist multiple objects under the same transaction.
If your application requires more complex persistence logic, the best approach is to introduce a persistence service which exposes only a limited set of functions to the client classes, for example
def persist(objectsofTypeA:Traversable[A],objectsOfTypeB:Traversable[B])
Please also note that according to your application complexity, you might want to expose this logic in different fashions:
as a singleton object in the case your application is simple, and you do not want your persistence logic to be pluggable
through a singleton object which acts as a sort as a "application context", so that in your application at startup you can decide which persistence logic you want to use.
with some sort of lookup service pattern, if your application is distributed.

Related

How to properly pass many dependencies (external APIs) to a class in Scala?

How to properly pass many dependencies (external APIs) to a class in Scala?
I'm working on the application that uses many APIs to collect data. For API's I have trait like below.
trait api {
def url: Foo
def parse: Bar
}
Also, there are about 10 implementations of the api trait (one for each API). Inside a parent actor, I want to create a child actor for every external API. I created new trait and implementation,
trait ExternalApis {
val apiList: List[api]
}
object MyApis extends ExternalApis {
val apiList = List(new ApiImpl1, ..., new ApiImpl10)
}
so now I can pass MyApis object (or any other implementation of ExternalApis) to parent actor and map over apiList for creating such child actors.
It seems to me I'm missing something. Are there more proper ways to do it?
The implementation that you have made looks nearly ready. Just something I would like to add are:
Passing an API List may not be the most ideal way to do such a thing. Anytime you would like to add/remove something to the API list, you would have to change different areas of the code. A suggestion would be to read this from a config folder, where the config folders would contain things such as url, username, password etc.
If you could provide more insight on the usage of these API's, it would help my answer a lot.
Hope this helped!

DDD abstraction over infrastructure code

I am creating a repository in my project which will be responsible for all storage operations for a User entity. I will use mongo as the db and mongoreactive as the client. The problem which I have now is about types.
trait UserRepository {
save(user: User) : ?
}
trait MongoUserRepository extends UserRepository {
save(user: User) : Future[WriteResult] = {
collection.insert(user)
}
}
How in my domain should I model WriteResult which comes from MongoReactive? I do not want it to leak into my domain. Is there any existing pattern or a good practice?
How in my domain should I model WriteResult which comes from MongoReactive? I do not want it to leak into my domain. Is there any existing pattern or a good practice?
The usual practice is that the domain would define the UserRepository trait as a service provider interface (spi) that the persistence infrastructure would need to support. Fundamentally, it's a way of expressing the usage requirements that the model imposes on persistence.
Using the language of Command Query Separation, save is a command: it's an operation that changes the state of the repository. So the implementation of the trait should conform to your local coding standard for implementing a command.
Greg Young on (generic) repositories:
What exactly was the intent of the repository pattern in the first place? Looking back to [DDD, Evans] one will see that it is to represent a series of objects as if they were a collection in memory so that the domain can be freed of persistence concerns. In other words the goal is to put collection semantics on the objects in persistence.
So you could also to your collections library for inspiration.
But generally speaking, the most common choice would look like
trait UserRepository {
save(user: User) : Unit
}
So that is the contract your specific implementations would be expected to satisfy.
In MongoUserRepository, you adapt the implementation of your persistence solution to satisfy the contract. In this case that would mean unpacking the Future, inspecting the WriteResult for errors, and throwing an exception if the write was unsuccessful.
With save(user: User) : Unit you implicitly put a requirement on your clients to watch for repository failure (for example: in case of db failure)
Other way around - the repository is a service provider interface; this design doesn't constrain the clients, but the providers. In the lingo of hexagonal architecture, I'm defining a secondary port and constraining the secondary adapter to conform to the contract of the port.
The motivation is exactly the one you describe: the repository consumer is supposed to be isolated from the protocol required to interact with the selected persistence solution. The domain model sits in the middle of the business universe, and the adapter insulates the business universe from reality.
Evans Chapter 6 raises the management challenge of "preventing the model from getting swamped by the complexity of managing the (domain object) life cycle". Repositories provide "the means of finding and retrieving persistent objects while encapsulating the immense infrastructure involved.
The repository is a firewall.
What we are addressing here is separation of concerns; the domain model describes your business logic. We want to be able to see the business case clearly, and that's not going to be possible if we have to explicitly manage what happens in the event that a mutable, in memory, collection fails catastrophically on modification. The pragmatic answer is to nope out and let the application handle it.
That said... I deliberately hedged above when I wrote "conform to your local coding standard". If your local guidelines use railway oriented programming, or message driven, then by all means line it up. There's absolutely no reason why the domain model should care whether storage is synchronous or asynchronous, local or remote, etc.
But if your domain model starts to fill up with match expressions that describe implementation concerns, I'd say you've lost the plot somewhere.
When I was implementing the same repository, I ended up extracting WriteResult value I was most interested in. In my case I ended up with the following signature:
trait UserRepository {
save(user: User) : Future[Option[String]]
}
which returns either some error message or nothing. As a result implementation will be like this:
trait MongoUserRepository extends UserRepository {
save(user: User) : Future[Option[String]] = {
collection.insert(user).map(_.errmsg)
}
}
I ended up with this implementation because I do not lose exception message in case of exception.
Alternative options could be to map insertion result to Boolean:
trait UserRepository {
save(user: User) : Future[Boolean]
}
trait MongoUserRepository extends UserRepository {
save(user: User) : Future[Boolean] = {
collection.insert(user).map(_.ok)
}
}
But in this case you will lose exception message. Sometimes it can be fine however it depends on your exact case.
UPDATE: The answer posted above is valid for 0.11 version. In 0.12 method errmsg in WriteResult was removed. Alternatively you can use writeErrors and in case Seq is not empty you extract all errmsgs from all WriteError.
Hope it helps, sir!

How do I specify type parameters via a configuration file?

I am building a market simulator using Scala/Akka/Play. I have an Akka actor with two children. The children need to have specific types which I would like to specify as parameters.
Suppose that I have the following class definition...
case class SecuritiesMarket[A <: AuctionMechanismLike, C <: ClearingMechanismLike](instrument: Security) extends Actor
with ActorLogging {
val auctionMechanism: ActorRef = context.actorOf(Props[A], "auction-mechanism")
val clearingMechanism: ActorRef = context.actorOf(Props[C], "clearing-mechanism")
def receive: Receive = {
case order: OrderLike => auctionMechanism forward order
case fill: FillLike => clearingMechanism forward fill
}
}
Instances of this class can be created as follows...
val stockMarket = SecuritiesMarket[DoubleAuctionMechanism, CCPClearingMechanism](Security("GOOG"))
val derivativesMarket = SecuritiesMarket[BatchAuctionMechanism, BilateralClearingMechanism](Security("SomeDerivative"))
There are many possible combinations of auction mechanism types and clearing mechanism types that I might use when creating SecuritiesMarket instance for a particular model/simulation.
Can I specify the type parameters that I wish to use in a given simulation in the application.conf file?
I see two questions here.
Can I get a Class instance from a String?
Yes.
val cls: Class[DoubleAuctionMechanism] = Class.forName("your.app.DoubleAuctionMechanism").asInstanceOf[Class[DoubleAuctionMechanism]]
You would still need the cast, as forName returns Class[_].
Can I instantiate a type with type parameters are not known compile time?
Well sort of, but not really.
object SecuritiesMarket {
def apply[A, C](clsAuc: Class[A], clsClr: Class[C])(security: Security): SecuritiesMarket[A, C] = {
SecuritiesMarket[A, C](security)
}
}
I think auction mechanisms and clearing mechanisms are dependencies for SecurityMarket. I'm guessing you instantiate them in its constructor somehow (how?). If that's the case why not just pass them in as a constructor parameter?
Edit:
I don't see how I could create the child actors inside SecurityMarket
Answering this in the comments; Props[T] can also be written as Props[T](classOfT), which can be simplified as Props(classOfT). Those three are the same. So the following code:
val auctionMechanism: ActorRef = context.actorOf(Props[A], "auction-mechanism")
Can be replaced with:
val classOfA = Class.forName("path.to.A")
val auctionMechanism: ActorRef = context.actorOf(Props(classOfA), "auction-mechanism")
First, application.conf is a runtime artifact and its contents are as far as I know not normally parsed at compile time. When the file is parsed at runtime, the parser creates an instance of the class Config which then controls the Akka setup.
The Typesafe Config library project readme is quite nice and the linked documentation has all of the details:
https://github.com/typesafehub/config/blob/master/README.md.
Second, since template parameters are not available at runtime because of type erasure, you can't normally use application.conf to control templating. You could create a custom build step to parse application.conf and modify your code before compilation, but this is maybe not what you want. (And if you do want a custom build step, perhaps a different .conf would be appropriate.)
Instead you might try simply eliminating the type parameters for the securities market class. Then create a single, simple implementation of the auction and clearing actors. Implement these actors by reading the names of the respective mechanisms from application.conf, instantiating the configured mechanism reflectively, and delegating to the instantiated mechanism. The mechanism classes could be independent of Akka, which is perhaps nice if that's where you keep most of your logic?

Play 2.0 models best practices

I am looking for best practices regarding models and ways to persist objects in database with play 2.0. I have studied the Play and typesafe samples for play 2.0 using scala.
What I understand is :
The model is defined in a case class
All the insert/update/delete/select are defined in the companion object of this case class
So if I need to update my Car object to define a new owner i will have to do:
val updatedCar = myCar.copy(owner=newOwner)
Car.update(updatedCar)
// or
Car.updateOwner(myCar.id.get, newOwner)
I am wondering why the update or delete statements are not in the case class itself:
case class Car(id: Pk[Long] = NotAssigned, owner: String) {
def updateOwner(newOwner: String) {
DB.withConnection { implicit connection =>
SQL(
"""
update car
set owner = {newOwner}
where id = {id}
"""
).on(
'id -> id,
'newOwner -> newOwner
).executeUpdate()
}
copy(owner = newOwner)
}
}
Doing so would permit to do:
val updatedCar = myCar.updateOwner(newOwner)
Which is what I used to do with Play 1.X using Java and JPA.
Maybe the reason is obvious and due to my small knowledge of Scala.
I think part of the reason is the favoring of immutability in functional languages like Scala.
In your example, you modify 'this.owner'. What's your equivalent operation look like for a delete, and what happens to "this"?
With a companion object, it seems a bit more clear that the passed object (or ID) is not modified, and the returned object or ID is the relevant result of the operation.
Then also, I think another part of the issue is that your example requires an instance first. When you delete an Object, what if you just want to delete by Id you got off a form, and don't want to first build a whole instance of the object you intend to delete?
I've been playing with play2.0 with mongo, and my companion objects look like:
object MyObject extends SalatDAO[MyObject,ObjectId] (collection = getCollection("objectcollection")) {
}
These companion objects inherit CRUD like operations from SalatDAO (MyObject.save(), MyObject.find(), etc). I'm not entirely clear on how it is implemented internally, but it works nicely.

Serialize Function1 to database

I know it's not directly possible to serialize a function/anonymous class to the database but what are the alternatives? Do you know any useful approach to this?
To present my situation: I want to award a user "badges" based on his scores. So I have different types of badges that can be easily defined by extending this class:
class BadgeType(id:Long, name:String, detector:Function1[List[UserScore],Boolean])
The detector member is a function that walks the list of scores and return true if the User qualifies for a badge of this type.
The problem is that each time I want to add/edit/modify a badge type I need to edit the source code, recompile the whole thing and re-deploy the server. It would be much more useful if I could persist all BadgeType instances to a database. But how to do that?
The only thing that comes to mind is to have the body of the function as a script (ex: Groovy) that is evaluated at runtime.
Another approach (that does not involve a database) might be to have each badge type into a jar that I can somehow hot-deploy at runtime, which I guess is how a plugin-system might work.
What do you think?
My very brief advice is that if you want this to be truly data-driven, you need to implement a rules DSL and an interpreter. The rules are what get saved to the database, and the interpreter takes a rule instance and evaluates it against some context.
But that's overkill most of the time. You're better off having a little snippet of actual Scala code that implements the rule for each badge, give them unique IDs, then store the IDs in the database.
e.g.:
trait BadgeEval extends Function1[User,Boolean] {
def badgeId: Int
}
object Badge1234 extends BadgeEval {
def badgeId = 1234
def apply(user: User) = {
user.isSufficientlyAwesome // && ...
}
}
You can either have a big whitelist of BadgeEval instances:
val weDontNeedNoStinkingBadges = Map(
1234 -> Badge1234,
5678 -> Badge5678,
// ...
}
def evaluator(id: Int): Option[BadgeEval] = weDontNeedNoStinkingBadges.get(id)
def doesUserGetBadge(user: User, id: Int) = evaluator(id).map(_(user)).getOrElse(false)
... or if you want to keep them decoupled, use reflection:
def badgeEvalClass(id: Int) = Class.forName("com.example.badge.Badge" + id + "$").asInstanceOf[Class[BadgeEval]]
... and if you're interested in runtime pluggability, try the service provider pattern.
You can try and use Scala Continuations - they can give you the ability to serialize the computation and run it at later time or even on another machine.
Some links:
Continuations
What are Scala continuations and why use them?
Swarm - Concurrency with Scala Continuations
Serialization relates to data rather than methods. You cannot serialize functionality because it is a class file which is designed to serialize that and object serialization serializes the fields of an object.
So like Alex says, you need a rule engine.
Try this one if you want something fairly simple, which is string based, so you can serialize the rules as strings in a database or file:
http://blog.maxant.co.uk/pebble/2011/11/12/1321129560000.html
Using a DSL has the same problems unless you interpret or compile the code at runtime.