A demo application written in TypeScript and NestJS, using Axon Synapse and Axon Server.
Additionally, the application is using fmodel-ts to implement CQRS and Event Sourcing patterns effectively.
It focuses around a simple giftcard domain, designed to show robust implementation of DDD/CQRS/ES concepts.
A bit simplified, this architectural style is characterized by two key architectural attributes:
-
There is a core with the core business logic, and a shell that handles interactions with the outside world, such as persisting data in databases or providing UIs to interact with end users.
-
The shell can call the core, but the core cannot call the shell and the core is even unaware of the existence of the shell. This is also known as the Dependency Rule(s).
-
It is similar to
Hexagonal Architecture
,Ports and Adapters
,Clean Architecture
,Onion Architecture
which have these two attributes in common.
In this demo we have categorized the code into three layers:
Domain
- pure declaration of the program logic, the core, the inner layer, the part that is not aware of the outside world, the part that is testable in isolation, the part that is reusable.- gift-card.command-handler.ts (
command side
) - gift-card.event-handler.ts (
query side
)
- gift-card.command-handler.ts (
Application
- orchestrates the execution of the logics, by loading the state from theInfrastructure / Fetch
, calling theDomain
logic, and persisting the state back to theInfrastructure / Save
.- gift-card.command-handler.aggregate.ts (
command side
) - gift-card.event-handler.materialized-view.ts (
query side
)
- gift-card.command-handler.aggregate.ts (
Adapters/Infrastructure
- infrastructure code, the shell, the outer layer, the part that is aware of the outside world.- gift-card.command-handler.aggregate.controller.ts (
command side
) - HTTP command subscriber/callback - gift-card.command-gateway.ts (
command side
) - HTTP command publisher - gift-card.event-repository.ts (
command side
) - Axon Server event repository - gift-card.event-handler.materialized-view.controller.ts (
query side
) - HTTP event subscriber/callback - gift-card.view-state-repository.ts (
query side
) - Postgres DB view state repository - gift-card.controller.ts (
command side + query side
) - HTTP/REST API, facing users
- gift-card.command-handler.aggregate.controller.ts (
Additionally, the components are split per command and query side of the application. This is CQRS pattern influencing the structure of the application.
$ npm install
# development
$ npm run start
# watch mode
$ npm run start:dev
# production mode
$ npm run start:prod
Set the correct :
- download latest version of Synapse JAR and copy it to synapse folder. Check the synapse/Dockerfile for the exact name of the JAR file.
docker-compose up -d
To shut it down:
docker-compose down -v
or, run Axon Server Enterprise Edition
Set the correct :
- license in axoniq.license.
docker-compose -f docker-compose-ee.yml up -d
To shut it down:
docker-compose -f docker-compose-ee.yml down -v
# unit tests
$ npm run test
# e2e tests
$ npm run test:e2e
# test coverage
$ npm run test:cov
Check the HTTP scratch file(s)
that you can run and explore the application:
Run Axon Server, Axon Synapse and Postgres
- Download
- http://localhost:5432/
- docker
docker run --name postgres -e POSTGRES_PASSWORD=postgres -p 5432:5432 -d postgres
Created with ❤️ by AxonIQ