The goal for this project is to demonstrate how to start easily a new scala 2.13 project (using FP techniques? :) ).
- JDK 8
- SBT
- akka-http as the web server. I could have gone with finch, twitter server, or http4s here as well.
- Circe for json serialization
- Cats for FP awesomeness
- Scapegoat for linting
- ScalaTest for test
Domain driven design is all about developing a ubiquitous language, which is a language that you can use to discuss your software with business folks (who presumably do not know programming).
DDD is all about making your code expressive, making sure that how you talk about your software materializes in your code. One of the best ways to do this is to keep you domain pure. That is, allow the business concepts and entities to be real things, and keep all the other cruft out. However, HTTP, JDBC, SQL are not essential to domain, so we want to decouple those as much as possible.
In concert with DDD, the Onion Architecture and Hexagonal Architecture from Cockburn give us patterns on how to separate our domain from the ugliness of implementation.
We fit DDD an Onion together via the following mechanisms:
The domain package
The domain package constitutes the things inside our domain. It is deliberately free of the ugliness of JDBC, JSON, HTTP, and the rest.
We use Services
as coarse-grained interfaces to our domain. These typically represent real-world use cases. Often times, you see a 1-to-1 mapping of Services
to R
or HTTP API calls your application surfaces.
Inside of the domain, we see a few concepts:
Service
- the coarse grained use cases that work with other domain concepts to realize your use-casesRepository
- ways to get data into and out of persistent storage. Important: Repositories do not have any business logic in them, they should not know about the context in which they are used, and should not leak details of their implementations into the world.payloads
ormodels
- things likeTweet
, etc are all domain objects. We keep these lean (i.e. free of behavior).
The repository package
The repository package is where the ugliness lives. It has JDBC things, and the like.
it contains implementations of our Repositories
. We may have 2 different implementations, an in-memory version as well as a doobie version.
The http package It contains the HTTP endpoints that we surface via akka-http. You will also typically see JSON things in here via circe
The util package The util package could be considered infrastructure, as it has nothing to do with the domain.
NOTE
All business logic is located in domain
package, every package inside is
related to some domain.
Service classes contains high level logic that relate to data manipulation, that means that services MUST NOT implement storage.
For storage there are dedicated classes.
1.application.conf
1.stage.application.conf
1.prod.application.conf
We use Pure Config to load configuration objects when the application starts up. pure config Provides a neat mapping of config file to case classes for us, so we really do not have to do any code.
To run project locally and load the corresponding secretes, it is recommended to choose one of the following alternatives.
In order to run locally on a developer machine via the command line, go to source folder and execute
~/scala213/> sbt runServer
For <command>
use one of ~compile | test | run
FIXME
- Open settings (
File -> Settings or CTRL+ALT+S
) - Choose Plugins
- Open "browse repositories" window and type
BashSupport
- Click "Install" button and wait until the installation completes
- Restart Intellij IDEA
- Open Run/Debug Configuration (
Run -> Edit Configurations
) - Click "+" button and select "Bash" item from drop down
- Give a name and select
sbt
file from source code - Enter
run
into "Program arguments" field - Click "Apply" and "OK"
- Click green button on the right side at the top of the window (or
Shift+F10
)
Pre Commit is a project on github to setup and maintain
git commit hooks. The default hooks are defined in .pre-commit-config.yaml
For installation on osx run
brew install pre-commit
To setup the hooks with pre-commit run:
pre-commit install -f --install-hooks
After that scalafmt checks your changed files for codestyle:
Note: Conflicts should be resolved
This section describes how to deploy scala213
to either STAGE
or PROD
.
sbt dependencyUpdates
Lists newer versions of integrated dependencies from Maven/Ivy
sbt dependencyUpdates
Linting is done via scapegoat. It is a static code analyzer inspecting the code with a set of 117 rules. Certain files can be excluded, rules can be changed. Configuration is described here.
The report can be picked up by Jenkins and should be part of the deployment pipeline.
Not to be confused with Sbt's "publishing"!.
haha FIXME
haha FIXME
-
For setting up the initial
seed
structure, we utilized Scala Pet Store. -
For STAGE/ PROD configuration, we utilized Production Configuration
Pureconfig's config file does not support uppercase and underscores. Read here
In order to use cats...
Run the tests with enabled coverage:
$ sbt clean test
To generate the coverage reports run
$ sbt coverageReport
Coverage reports will be in target/scala-2.12/scoverage-report/index.html.