All Projects → j5ik2o → scala-ddd-base

j5ik2o / scala-ddd-base

Licence: MIT license
scala-ddd-base provides traits to support for ddd repositories and aggregates.

Programming Languages

scala
5932 projects
FreeMarker
481 projects

Labels

Projects that are alternatives of or similar to scala-ddd-base

muon-java
Muon Core for the JVM. APIs and Microservices taken to the next level
Stars: ✭ 18 (-55%)
Mutual labels:  ddd
EDT.DDD.Sample
一个基于.NET 5开发的DDD示例WebAPI项目
Stars: ✭ 13 (-67.5%)
Mutual labels:  ddd
firebase-event-sourcing
Event Sourcing + CQRS + DDD for Firebase
Stars: ✭ 14 (-65%)
Mutual labels:  ddd
archimedes-jvm
Archimedes's implementation for the Java Virtual Machine (JVM)
Stars: ✭ 24 (-40%)
Mutual labels:  ddd
e-shop
Sample Spring Cloud microservices e-shop.
Stars: ✭ 48 (+20%)
Mutual labels:  ddd
awesome-talks
Awesome talks about event sourcing, cqrs, microservices, funcional programming ...
Stars: ✭ 23 (-42.5%)
Mutual labels:  ddd
Joker
An example of microservices container based application which implemented different approaches within each microservice (DDD, CQRS, Simple CRUD)
Stars: ✭ 41 (+2.5%)
Mutual labels:  ddd
QrF.Core
基于.net core 2.2 的微服务框架
Stars: ✭ 19 (-52.5%)
Mutual labels:  ddd
LinqSpecs
A toolset for use the specification pattern in LINQ queries.
Stars: ✭ 161 (+302.5%)
Mutual labels:  ddd
eventuous
Minimalistic Event Sourcing library for .NET
Stars: ✭ 236 (+490%)
Mutual labels:  ddd
eventcatalog
Discover, Explore and Document your Event Driven Architectures powered by Markdown.
Stars: ✭ 392 (+880%)
Mutual labels:  ddd
QuerySpecification
Abstract package for building query specifications in your domain model.
Stars: ✭ 18 (-55%)
Mutual labels:  ddd
jobofferbackend
This project is a real-world example of DDD in a backend application It applies the concept of Entity, Value Object, Root, Aggregate, Services, Repositories and Ubiquitous Language.
Stars: ✭ 15 (-62.5%)
Mutual labels:  ddd
bdd-for-all
Flexible and easy to use library to enable your behavorial driven development (BDD) teams to easily collaborate while promoting automation, transparency and reporting.
Stars: ✭ 42 (+5%)
Mutual labels:  ddd
city-codes
Brazilian city names and official codes, IBGE, LexML and others
Stars: ✭ 39 (-2.5%)
Mutual labels:  ddd
event-store-mgmt-ui
Event Store Management UI
Stars: ✭ 23 (-42.5%)
Mutual labels:  ddd
educational-platform
Modular Monolith Java application with DDD
Stars: ✭ 124 (+210%)
Mutual labels:  ddd
go-ddd-api
API with domain driven design approach using golang, gorm, and mysql
Stars: ✭ 136 (+240%)
Mutual labels:  ddd
MonolithicArchitecture
This repository presents an approach on how to build an application using Monolithic architecture, ASP.NET Core, EntityFrameworkCore, Identity Server, CQRS, DDD
Stars: ✭ 18 (-55%)
Mutual labels:  ddd
archimedes-js
Archimedes's implementation for JavaScript and TypeScript
Stars: ✭ 34 (-15%)
Mutual labels:  ddd

scala-ddd-base

CircleCI Maven Central Scaladoc License: MIT

scala-ddd-base provides traits to support for ddd repositories and aggregates.

Installation

Add the following to your sbt build (Scala 2.11.x, 2.12.x):

resolvers += "Sonatype OSS Release Repository" at "https://oss.sonatype.org/content/repositories/releases/"

val scalaDddBaseVersion = "..."

libraryDependencies ++= Seq(
  "com.github.j5ik2o" %% "scala-ddd-base-core" % scalaDddBaseVersion,
  // Please set as necessary
  // "com.github.j5ik2o" %% "scala-ddd-base-slick" % scalaDddBaseVersion,
  // "com.github.j5ik2o" %% "scala-ddd-base-skinny" % scalaDddBaseVersion,
  // "com.github.j5ik2o" %% "scala-ddd-base-redis" % scalaDddBaseVersion,
  // "com.github.j5ik2o" %% "scala-ddd-base-memcached" % scalaDddBaseVersion,
  // "com.github.j5ik2o" %% "scala-ddd-base-dynamodb" % scalaDddBaseVersion,
  // "com.github.j5ik2o" %% "scala-ddd-base-memory" % scalaDddBaseVersion
)

Core traits

The following provides basic abstract methods.

  • AggregateSingleReader
  • AggregateSingleWriter
  • AggregateMultiReader
  • AggregateMultiWriter
  • AggregateSingleSoftDeletable
  • AggregateSingleHardDeletable
  • AggregateMultiSoftDeletable
  • AggregateMultiHardDeletable

Support traits

The following provides an implementation for each ORM/KVS.

  • AggregateSingleReadFeature
  • AggregateSingleWriteFeature
  • AggregateMultiReadFeature
  • AggregateMultiWriteFeature
  • AggregateSingleSoftDeleteFeature
  • AggregateSingleHardDeleteFeature
  • AggregateMultiSoftDeleteFeature
  • AggregateMultiHardDeleteFeature

The supported ORM/KVS/Cache is below.

Example

Please mix in the core and support traits to your implementation. Slick, SkinnyORM, Memcached, Redis, Memory etc. You can also choose the implementation as you like.

trait UserAccountRepository[M[_]]
    extends AggregateSingleReader[M]
    with AggregateMultiReader[M]
    with AggregateSingleWriter[M]
    with AggregateMultiWriter[M]
    with AggregateSingleSoftDeletable[M]
    with AggregateMultiSoftDeletable[M] {
  override type IdType        = UserAccountId
  override type AggregateType = UserAccount
}

object UserAccountRepository {

  type OnRedis[A]     = ReaderT[Task, RedisConnection, A]
  type OnMemcached[A] = ReaderT[Task, MemcachedConnection, A]
  type OnDynamoDB[A]  = Task[A]
  type OnMemory[A]    = Task[A]
  type BySlick[A]     = Task[A]
  type BySkinny[A]    = ReaderT[Task, DBSession, A]
  type ByFree[A]      = Free[UserRepositoryDSL, A]

  def bySlick(profile: JdbcProfile, db: JdbcProfile#Backend#Database): UserAccountRepository[BySlick] =
    new UserAccountRepositoryBySlick(profile, db)

  def bySkinny: UserAccountRepository[BySkinny] = new UserAccountRepositoryBySkinny

  def onRedis(
      expireDuration: Duration
  )(implicit actorSystem: ActorSystem): UserAccountRepository[OnRedis] =
    new UserAccountRepositoryOnRedis(expireDuration)

  def onMemcached(
      expireDuration: Duration
  )(implicit actorSystem: ActorSystem): UserAccountRepository[OnMemcached] =
    new UserAccountRepositoryOnMemcached(expireDuration)
    
  def onDynamoDB(dynamoDbAsyncClient: DynamoDbAsyncClient): UserAccountRepository[OnDynamoDB] =
    new UserAccountRepositoryOnDynamoDB(DynamoDBTaskClientV2(DynamoDBAsyncClientV2(underlying))

  def onMemory(minSize: Option[Int] = None,
               maxSize: Option[Int] = None,
               expireDuration: Option[Duration] = None,
               concurrencyLevel: Option[Int] = None,
               maxWeight: Option[Int] = None): UserAccountRepository[OnMemory] =
    new UserAccountRepositoryOnMemory(minSize, maxSize, expireDuration, concurrencyLevel, maxWeight)
    
}

Usage

  • for Slick3
val userAccountRepository: UserAccountRepository[BySlick] = UserAccountRepository.bySlick(dbConfig.profile, dbConfig.db)
val resultTask: Task[UserAccount] = for {
  _ <- userAccountRepository.store(userAccount)
  result <- userAccountRepository.resolveBy(userAccount.id)
} yield result

val resultFuture: Future[UserAccount] = resultTask.runToFuture
  • for SkinnyORM
val userAccountRepository: UserAccountRepository[BySkinny] = UserAccountRepository.bySkinny
val resultTask: Task[UserAccount] = for {
  _ <- userAccountRepository.store(userAccount)
  result <- userAccountRepository.resolveBy(userAccount.id)
} yield result

val resultFuture: Future[UserAccount] = resultTask.run(AutoSession).runToFuture
  • for Memcached
val userAccountRepository: UserAccountRepository[OnMemcached] = UserAccountRepository.onMemcached(expireDuration = 5 minutes)
val resultFuture: Future[UserAccount] = connectionPool
  .withConnectionF { con =>
    (for {
      _ <- userAccountRepository.store(userAccount)
      r <- userAccountRepository.resolveById(userAccount.id)
    } yield r).run(con)
  }
  .runToFuture
  • for Redis
val userAccountRepository: UserAccountRepository[OnRedis] = UserAccountRepository.onRedis(expireDuration = 5 minutes)
val resultFuture: Future[UserAccount] = connectionPool
  .withConnectionF { con =>
    (for {
      _ <- userAccountRepository.store(userAccount)
      r <- userAccountRepository.resolveById(userAccount.id)
    } yield r).run(con)
  }
  .runToFuture
  • for DynamoDB
val userAccountRepository: UserAccountRepository[OnDynamoDB] = UserAccountRepository.onDynamoDB(dynamoDbAsyncClient)
val resultFuture: Future[UserAccount] = (for {
  _ <- userAccountRepository.store(userAccount)
  r <- userAccountRepository.resolveById(userAccount.id)
} yield r).runToFuture
  • for Memory(Guava Cache)
val userAccountRepository: UserAccountRepository[OnMemory] = UserAccountRepository.onMemory(expireAfterWrite = Some(5 minutes))
val resultFuture: Future[UserAccount] = (for {
  _ <- repository.store(userAccount)
  r <- repository.resolveById(userAccount.id)
} yield r).runToFuture
  • for Free
val free: UserAccountRepository[ByFree] = UserAccountRepositoryByFree
val program: Free[UserRepositoryDSL, UserAccount] = for {
  _      <- free.store(userAccount)
  result <- free.resolveById(userAccount.id)
} yield result

val slick = UserAccountRepository.bySlick(dbConfig.profile, dbConfig.db)
val resultTask: Task[UserAccount] = UserAccountRepositoryOnFree.evaluate(slick)(program)
val resultFuture: Future[UserAccount] = evalResult.runToFuture

// if evaluation by skinny 
// val skinny     = UserAccountRepository.bySkinny
// val resultTask: Task[UserAccount] = UserAccountRepositoryOnFree.evaluate(skinny)(program)
// val resultFuture: Future[UserAccount] = evalResult.run(AutoSession).runToFuture
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].