Entities
Entity modelling, including entity relations.
Aggregate
Group of entities that can be interacted with as a single object.
Commands
Decoupled command objects that perform change operations on entities and aggregates.
Queries
Decoupled query objects that fetch single entities and collections of entities.
Validation
- Command, query, entity and aggregate validation.
- Static validation that can be defined at built-time.
- Dynamic validation that can interact with live state at run-time.
- Integrated with IAM so that different roles are permitted to perform different commands and queries.
Transitions / entity lifecycles
Ability to move entities through stages in a lifecycle. For example, draft products that can be published as products, or baskets that become orders via a checkout process. This makes validation more flexible by allowing a gradual assembly of a valid entity via intermediate stages.
Interfaces
Decoupled interfaces that allow interaction with the application. Any command or query can be issued via any supported interface.
HTTP
HTTP APIs, such as REST, OpenAPI, GraphQL.
Local CLI
Heavy command line interface that runs application code locally to issue commands and queries.
Network CLI
Light command line interface that issues commands and queries over the network to an API.
Web
Web user interface that issues commands and queries over the network to an API. Could be purely HTML based, or use a web framework such as React or htmx.
SDK
Abstract interface in a programming language for use by other developers to conveniently issue commands and queries over the network to an API.
Mobile / iOS / Android
Mobile application user interfaces that issue commands and queries over the network to an API.
Desktop
Desktop application user interface that issues commands and queries over the network to an API.
Slack
Slack chat integration built using the Slack SDK to allow issuing commands and queries via intermediate event handlers on the application side.
Events
- Entity events (create, update, delete)
- Configurable as synchronous or asynchronous via jobs.
Tasks
- Asynchronous jobs that are handled on a queue.
- Can bundle sub-tasks into a parent task and fan-out the handling.
- Can mark a task as dependent on another so that the dependent tasks are handled sequentially.
- Incremental progress can be reported back to a Job entity, which can then be pushed out via subscriptions or notifications.
Authentication
- User and service authentication.
- Third-party authentication via SAML.
- External authentication via event handlers such as Slack event handlers, or OS users for the local CLI.
Authorization / Permissions / IAM
- Static IAM that can be defined at build-time and hard-coded in the application. This is fast.
- Dynamic IAM that can be configured and applied at run-time, allowing it to fetch live state. This is slow.
Notifications
- SMS
- Outbound web-hooks
- Web push
- Mobile push
- Slack
- Telegram
Inbound web-hooks
Convenience for setting up inbound web-hook endpoints for other systems to call into and trigger events and audit trails.
Subscriptions
Allow clients to subscribe to updates via websocket.
Entity subscription
Subscribe to changes to a specific individual entity or aggregate.
Series subscription
Receive incremental updates to a series, allowing chat applications and live update feeds.
Scheduling
- Cron-like scheduling of any command or task on a recurring basis.
- One-off scheduling of a command or task at a specific time.
Batch processing
- Handle changes across many entities by batching up work and handling it in tasks.
- Allow spreading batch work over intervals, e.g. “hourly once a week”. This means that one batch is processed every hour, with all entities covered once every week.
Filtered search
- AKA faceted search or layered search.
- Build a search index of an entity or aggregate.
- Allow client to specify filters on configurable facets.
- Results are paginated.
- Filter metadata is returned with paginated results, showing the count of entities matching each facet value.
- Common in e-commerce applications.
Infrastructure
- Framework assists with infrastructure management, based on configuration of other resources such as entities, drivers and so on.
- Docker
- AWS CloudFormation
- Terraform
Drivers
- Resources as configurable providers so that the business logic is abstracted from implementation.
- E.g. entities and aggregates can be backed by a datastore driver, which can be provided as different SQL databases, DynamoDB, filesystem, Redis etc.
- Static drivers are configured at build-time, so the resulting application only has that static driver available to it.
- Dynamic drivers are configured at run-time, so that the same application build can switch between drivers, for example in different environments.
Deployments
- Support for deployment management by making deployments a first-class concept and assisting with configuration of deployment tools such as Github Actions, CodeBuild and so on.
Logging
- Default logging on entities, aggregates, commands, queries, events, tasks.
- Driver-backed to allow configuring different log drivers.
- Integrates with infrastructure to set up logging appropriate to configured infrastructure.
Monitoring, alerting
- Driver-backed to allow configuring different log drivers.
- Integrates with infrastructure to set up monitoring appropriate to configured infrastructure.
Migrations
- Datastore migrations.
Auditing
- Support audit-trail logging to record commands, queries and tasks.
Introspection
- Application can dynamically inspect itself at runtime and show infrastructure data such as queue length.
Tests
Assistance with application test at different levels.
Unit
Tests for self-contained individual units such as classes and functions that don’t have any dependencies outside of the constructor or function arguments.
Process
Tests that run in a single OS process, with any external dependency either
replaced with an in-process driver or mocked out with tools such as
httpx-mock
and moto
. These are highly effective for debugging business
logic, but will miss issues in the integration between real resources.
Integration
Tests that run entirely on the local OS, with services like databases running in
Docker containers, and third-party APIs either mocked out with tools such as
httpx-mock
or as dummy implementations running in Docker containers. The
application under test runs in the same process as the tests to allow debugging
during integration tests.
Deployed / smoke
Tests that run against the application in deployed infrastructure such as AWS. These are few in number and aim for high-level sanity checks or smoke tests.
Environments
Runtime environment awareness which lets the application behave differently in different environments. Drivers can be specified per environment, for example the local development environment might use a different queue driver than the production deployment environment.
Local development
Feature flags
Configuration / settings
- Static configuration is specified at build-time and supplied to the application via environment variables or secure secrets. It cannot be changed at run-time. It only needs to be loaded once at application start-up.
- Dynamic configuration can be changed at run-time, either by administrators or users. It needs to be loaded before each relevant action in case it has changed.
Demos
Assistance for demoing features, for example a prompted command-line script that takes the demo presenter through a particular use-case.
Documentation
Assistance for documenting the application, for example by producing OpenAPI specifications.
Third-party interfaces
Support for modelling third-party APIs, which can facilitate test implementations and libraries.
Export
Ability to bulk export entities and aggregates in formats such as CSV and JSON.
Import
Ability to bulk import entities and aggregates from formats such as CSV and JSON. Can use tasks that handle the import asynchronously and report granular issues with individual rows.
Synchronisation
Two-way synchronisation with another system, so that updates flow in both directions. For example, stock counts can be updated both to and from a third-party sales system such as Amazon or Etsy.