Well, after several hours of thinking about it, I think I found a solution that will satisfy my needs. The goals I want to accomplish are as follows:
- Web GUI cannot make direct calls to the database; he needs to use a suitable model, which, in turn, will use the repository of some objects.
- It should be possible to test and deploy the whole thing as one package with a minimal configuration (at least for the development phase, and then it should be possible to easily switch to a more flexible solution).
- There should be no duplication of code (i.e. the same code in the service and web gui model)
- If one approach proves wrong, I need to be able to switch to another
What I forgot to say earlier is that my service will have a built-in cache used for aggregating and processing data, and then commits to the database with large chunks. It is also present on the chart.
My class structure will look like this:
| |- models |- IElementsRepository.scala |- ElementsRepositoryJSON.scala |- ElementsRepositoryDB.scala |- Element.scala |- Service |- Element.scala |- Web |- Element.scala |- controlers |- Element.scala |- views |- Element |- index.scala.html
So, it looks like a regular MVC web application, except for the fact that there are separate model classes for services and web gui that inherit from the main one.
In Element.scala, I will have an IElementsRepository object introduced using DI (possibly using Guice).
IElementsRepository have two specific implementations:
- ElementsRepositoryJSON allows you to retrieve data from a service via JSON
- ElementsRepositoryDB allows you to retrieve data from the local cache and database.
This means that depending on the active DI configuration, both services and web gui can receive data from another service or local / external storage.
Therefore, for early development, I can keep everything in one game! instance and use the direct cache and access to the database (via ElementsRepositoryDB), and then reconfigure the web gui to use JSON (via ElementsRepositoryJSON). It also allows me to run gui and service as separate instances, if I want. I can even configure the service to use other services as data providers (however, at the moment I have no such needs).
More or less, it will look like this:

source share