Skip to content
/ Wow Public

Modern Reactive CQRS Architecture Microservice development framework based on DDD and EventSourcing | 基于 DDD & EventSourcing 的现代响应式 CQRS 架构微服务开发框架

License

Notifications You must be signed in to change notification settings

Ahoo-Wang/Wow

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Wow:A Modern Reactive CQRS Architecture Microservice development framework based on DDD and EventSourcing

Wow : Modern Reactive CQRS Architecture Microservice development framework based on DDD and EventSourcing

中文文档

License GitHub release Maven Central Version Codacy Badge codecov Integration Test Status Awesome Kotlin Badge Ask DeepWiki

Domain-Driven | Event-Driven | Test-Driven | Declarative-Design | Reactive Programming | Command Query Responsibility Segregation | Event Sourcing

Quick Start

Use Wow Project Template to quickly create a DDD project based on the Wow framework.

Features Overview

Wow-Features

Architecture

Wow-Architecture

Command Processing Propagation Chain

Wow-WaitingForChain

Performance Test (Example)

  • Test Code: Example
  • Test Case: Add To Shopping Cart / Create Order
  • Command WaitStrategy: SENTPROCESSED

Deployment

Test Report

Add To Shopping Cart

WaitStrategy:SENT Mode, The AddCartItem command write request API After 2 minutes of stress testing, the average TPS was 59625, the peak was 82312, and the average response time was 29 ms.

AddCartItem-SENT

WaitStrategy:PROCESSED Mode, The AddCartItem command write request API After 2 minutes of stress testing, the average TPS was 18696, the peak was 24141, and the average response time was 239 ms.

AddCartItem-PROCESSED

Create Order

WaitStrategy:SENT Mode, The CreateOrder command write request API After 2 minutes of stress testing, the average TPS was 47838, the peak was 86200, and the average response time was 217 ms.

CreateOrder-SENT

WaitStrategy:PROCESSED Mode, The CreateOrder command write request API After 2 minutes of stress testing, the average TPS was 18230, the peak was 25506, and the average response time was 268 ms.

CreateOrder-PROCESSED

Event Sourcing

Wow-EventSourcing

Observability

Wow-Observability

OpenAPI (Spring WebFlux Integration)

Automatically register the Command routing processing function (HandlerFunction), and developers only need to write the domain model to complete the service development.

Wow-Spring-WebFlux-Integration

Test suite: 80%+ test coverage is very easy

Given -> When -> Expect .

Wow-CI-Flow

Preconditions

  • Understanding Domain Driven Design:《Implementing Domain-Driven Design》,《Domain-Driven Design: Tackling Complexity in the Heart of Software》
  • Understanding Command Query Responsibility Segregation(CQRS)
  • Understanding EventSourcing
  • Understanding Reactive Programming

Order Service(Kotlin)

Example-Order

Transfer(JAVA)

Example-Transfer

Unit Test Suite

80%+ test coverage is very easy.

Test Coverage

Given -> When -> Expect .

Aggregate Unit Test (AggregateVerifier)

Aggregate Test

class CartSpec : AggregateSpec<Cart, CartState>({
  on {
    val ownerId = generateGlobalId()
    val addCartItem = AddCartItem(
      productId = "productId",
      quantity = 1,
    )
    givenOwnerId(ownerId)
    whenCommand(addCartItem) {
      expectNoError()
      expectEventType(CartItemAdded::class)
      expectState {
        items.assert().hasSize(1)
      }
      expectStateAggregate {
        ownerId.assert().isEqualTo(ownerId)
      }
      fork {
        val removeCartItem = RemoveCartItem(
          productIds = setOf(addCartItem.productId),
        )
        whenCommand(removeCartItem) {
          expectEventType(CartItemRemoved::class)
        }
      }
      fork {
        whenCommand(DefaultDeleteAggregate) {
          expectEventType(DefaultAggregateDeleted::class)
          expectStateAggregate {
            deleted.assert().isTrue()
          }

          fork {
            whenCommand(DefaultDeleteAggregate) {
              expectErrorType(IllegalAccessDeletedAggregateException::class)
            }
          }
          fork {
            whenCommand(DefaultRecoverAggregate) {
              expectNoError()
              expectStateAggregate {
                deleted.assert().isFalse()
              }
              fork {
                whenCommand(DefaultRecoverAggregate) {
                  expectErrorType(IllegalStateException::class)
                }
              }
            }
          }
        }
      }
    }
  }
}
)

Saga Unit Test (SagaVerifier)

Saga Test

class CartSagaSpec : SagaSpec<CartSaga>({
  on {
    val ownerId = generateGlobalId()
    val orderItem = OrderItem(
      id = generateGlobalId(),
      productId = generateGlobalId(),
      price = BigDecimal.valueOf(10),
      quantity = 10,
    )
    whenEvent(
      event = mockk<OrderCreated> {
        every {
          items
        } returns listOf(orderItem)
        every {
          fromCart
        } returns true
      },
      ownerId = ownerId
    ) {
      expectCommandType(RemoveCartItem::class)
      expectCommand<RemoveCartItem> {
        aggregateId.id.assert().isEqualTo(ownerId)
        body.productIds.assert().hasSize(1)
        body.productIds.assert().first().isEqualTo(orderItem.productId)
      }
    }
  }
  on {
    name("NotFromCart")
    val orderItem = OrderItem(
      id = generateGlobalId(),
      productId = generateGlobalId(),
      price = BigDecimal.valueOf(10),
      quantity = 10,
    )
    whenEvent(
      event = mockk<OrderCreated> {
        every {
          items
        } returns listOf(orderItem)
        every {
          fromCart
        } returns false
      },
      ownerId = generateGlobalId()
    ) {
      expectNoCommand()
    }
  }
})

Design

Modeling

Single Class Inheritance Pattern Aggregation Pattern
Single Class - Modeling Inheritance Pattern- Modeling Aggregation Pattern- Modeling

Load Aggregate

Load Aggregate

Aggregate State Flow

Aggregate State Flow

Send Command

Send Command

Command And Event Flow

Command And Event Flow

Event Compensation

Use Case

Event-Compensation-UserCase

Execution Sequence Diagram

Event-Compensation

Dashboard

Compensation-Dashboard

Compensation-Dashboard

Compensation-Dashboard

Compensation-Dashboard-Error

About

Modern Reactive CQRS Architecture Microservice development framework based on DDD and EventSourcing | 基于 DDD & EventSourcing 的现代响应式 CQRS 架构微服务开发框架

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors 6