scalalibrary-design

Writing database library in Scala - initialization code


I wanted to write small library for Neo4j database in Scala language. This library will talk with Neo4j database and mostly map classes to nodes. I want to make it work like spray-json library: https://github.com/spray/spray-json

Anyway I was wondering about one thing, what is the best way to implement initialization code in library?

For example in Spring Data Neo4j when you create application context with Neo4j beans, the line val ctx = new ClassPathXmlApplicationContext(...) invokes some code that creates indexes in Neo4j based on annotations.

Should steps like that be achieved through using static methods in constructor/factory methods (in Scala it would probably be some companion object)? And if so, how would I proceed if I want no explicit invocation of initialization code, meaning the first time I use something from my library initialization happens but it is cached somewhere - I was thinking of using lazy vals to store required information for my library in this case.


Solution

  • Should steps like that be achieved through using static methods in constructor/factory methods (in Scala it would probably be some companion object)?

    No, the word initialization implies state and having global state is antipattern. I really like how casbah was designed:

    import com.mongodb.casbah.Imports._
    val mongoClient = MongoClient("localhost", 27017)
    
    val database = mongoClient("test")
    // now the actual work with databases and encompassed collections 
    db.collectionNames
    val coll = db("test")
    ...
    

    So now, I can have multiple instances of clients, which is really useful not only for the main app code, but for the testing. Moreover, having everything in object, as you proposed above, may complicate things in case of multi-threaded application.

    And if so, how would I proceed if I want no explicit invocation of initialization code, meaning the first time I use something from my library initialization happens but it is cached somewhere - I was thinking of using lazy vals to store required information for my library in this case.

    Why don't you roll out session-like (i.e. MongoClient in code above) object and cache everything inside it?

    FYI, loan pattern, it do not relate directly with your inquiry, but it's a good option when you implement scala APIs