🐍 Implementation of functional core & imperative shell web app. Hexagonal architecture with CQRS entrypoints. Domain designed referring to DDD patterns.
The fundamental reasoning and criteria for devising this architectural design was to answer: “**How can we best structure the application as to have independent, decoupled and easily testable and maintanble abstractions?”
This is a work that is inspired mainly from the ideas of Functional Core Imperative Shell, from hexagonal architecture’s Ports and Adapters) and from Dependency Inversion principles. The goal is to achieve:
domain
Imutability: Value Object
Object that is defined by its attributes. Which never mutate.
Identifiability: Entity
Object whose attributes change over time. Has an identity.
Register: Event
Represents something that has happened within the system.
Actions: Command
Represents some work and command that the system must perform.
Consistency and invariants: Aggregate
Object that semantically abstracts a business macro-entity. It is composed of Value Objects and Entities. It is domain’s entrypoint and where public domain services lives. It enables that we consider an aggregate as a whole, a single unity and, hence, preserve expected consistency inside those boundaries. Each operation within this bounded context ends in a consitent and expected state.
adapters
Implements interfaces between the system and external world (I/O)
Persistent storage: Repository
Couples with an aggregate to enable persistent storage. This adapter may implement a SQL, an S3, a DynamoDB or any other client connection.
Publishing: Event Publisher
Publishes events in external message buses.
services
Orchestrates domain and adapter’s workflows that are mapped to user stories.
Atomic operations: Unit of Work
Enables decoupling of service and data layer. A unit of work acts as a single entrypoint to persitent storage. It holds, for each atomic operation, aggregate state.
Communication: Message Bus
(barramento de mensagens)
Maps commands and events to handlers. Enables decoupling within service layer through a chain of handlers.
Orchestration: Handler
Workflow that must happen as a response to commands and events.
It is advisable to run this project under a specific environment running Python 3.7+
poetry
is being used to manage dependencies efficiently. Therefore, it’s as simple as
$ poetry install
In order to update database to recent changes on declared metadata, we’re using alembic
. By doing
alembic upgrade head
You should be able to reach most-recent state
TDD is being employed so in order to run and test implementations, abstracted to Makefile
:
$ make test
This is a self-study of the book Cosmic Python: Architectural Patterns.