makinacorpus / goat
Event store, domain repositories and preference API for PHP, with a Symfony bundle
Installs: 4 641
Dependents: 0
Suggesters: 0
Security: 0
Stars: 3
Watchers: 12
Forks: 0
Open Issues: 9
Requires
- php: >=8.0
- makinacorpus/goat-query: ^2.1.7 || ^3.0
- makinacorpus/message: ^1.0.2
- makinacorpus/normalization: ^1.0.1
- psr/log: ^1.0
- ramsey/uuid: ^3.8 || ^4
- symfony/event-dispatcher: ^4.4 || ^5.0 || ^6.0
Requires (Dev)
- makinacorpus/event-store: ^1.0.4
- makinacorpus/goat-query-bundle: >=2.0
- phpunit/phpunit: ^9
- symfony/config: ^5.4 || ^6.0
- symfony/console: ^5.4 || ^6.0
- symfony/dependency-injection: ^5.4 || ^6.0
- symfony/form: ^5.4 || ^6.0
- symfony/http-kernel: ^5.4 || ^6.0
- symfony/monolog-bundle: ^3.5
- symfony/serializer-pack: ^1.0|^5.0
- symfony/validator: ^5.4 || ^6.0
- symfony/yaml: ^5.4 || ^6.0
- twig/twig: ^2.5 || ^3.0
Suggests
- doctrine/dbal: For query builder usage over a Doctrine PDO connection
- doctrine/doctrine-bundle: For query builder usage over a Doctrine PDO connection
- makinacorpus/goat-query: For using PostgreSQL implementations of everything
- symfony/serializer-pack: For better object serialisation and normalisation within the bus
Replaces
- dev-master
- 5.0.x-dev
- 5.0.0-alpha5
- 5.0.0-alpha4
- 5.0.0-alpha3
- 5.0.0-alpha2
- 5.0.0-alpha1
- 4.0.x-dev
- 4.0.4
- 4.0.3
- 4.0.2
- 4.0.1
- 4.0.0
- 4.0.0-alpha19
- 4.0.0-alpha18
- 4.0.0-alpha17
- 4.0.0-alpha16
- 4.0.0-alpha15
- 4.0.0-alpha14
- 4.0.0-alpha13
- 4.0.0-alpha12
- 4.0.0-alpha11
- 4.0.0-alpha10
- 4.0.0-alpha9
- 4.0.0-alpha8
- 4.0.0-alpha7
- 4.0.0-alpha6
- 4.0.0-alpha5
- 4.0.0-alpha4
- 4.0.0-alpha3
- 4.0.0-alpha2
- 4.0.0-alpha1
- 3.1.x-dev
- 3.1.0
- 3.0.x-dev
- 3.0.4
- 3.0.3
- 3.0.2
- 3.0.1
- 3.0.0
- 3.0.0-alpha13
- 3.0.0-alpha12
- 3.0.0-alpha11
- 3.0.0-alpha10
- 3.0.0-alpha9
- 3.0.0-alpha8
- 3.0.0-alpha7
- 3.0.0-alpha6
- 3.0.0-alpha5
- 3.0.0-alpha4
- 3.0.0-alpha3
- 3.0.0-alpha2
- 3.0.0-alpha1
- 2.0.x-dev
- 2.0.0
- 2.0.0-alpha3
- 2.0.0-alpha2
- 2.0.0-alpha1
- 1.1.x-dev
- 1.1.18
- 1.1.17
- 1.1.16
- 1.1.15
- 1.1.14
- 1.1.13
- 1.1.12
- 1.1.11
- 1.1.10
- 1.1.9
- 1.1.8
- 1.1.7
- 1.1.6
- 1.1.5
- 1.1.4
- 1.1.3
- 1.1.2
- 1.1.1
- 1.1.0
- 1.0.x-dev
- 1.0.9
- 1.0.8
- 1.0.7
- 1.0.6
- 1.0.5
- 1.0.4
- 1.0.3
- 1.0.2
- 1.0.1
- 1.0.0
- dev-fix-abstract-event-store
- dev-projector-repo
- dev-add-projector
- dev-fix-symfony-di-extension
This package is not auto-updated.
Last update: 2024-10-04 00:02:10 UTC
README
Provides a set of tooling for domain driven design. Automatic integration to Symfony >= 4 is provided via makinacorpus/goat-bundle package.
Status
This was kind of micro-framework, including many features:
- Command bus logic with a command dispatcher and a command handler locator.
- Independent message broker implementation using PostgreSQL.
- A command for reading the message broker queue and send it into the command bus synchronous dispatcher.
- A name normalization and mapping API (e.g.
\App\Foo\Bar
toApp.Foo.Bar
) for sharing business identifier across techonology boundary. - Some rather generic, stable and functionnal event store implementation with a PostgreSQL driver.
- An event projector API for consuming event store events and projecting them into custom implementation, for populating read model databases.
- A legary repository pattern implementation.
- Preferences API restitued as pseudo Symfony environement variables.
- A Symfony bundle to tie everything.
All together this represents a huge functionnal surface, and many items in this list don't belong together.
The name goat
itself refers to something stupid or insecure.
This project has lived throught 4 production projects, and still exist and is maintained, but not for long.
Next version major, i.e. 5.x will be the last one, it reprensents the current state where:
- Preferences API no long exists, and has been moved to an independant package
makinacorpus/preferences-bundle
(you may look it up on packagist). - Repository pattern implementation has gone away, it was really in use in a
single project, and will remain minimally maintained (bugfixes only) in an
independent package as well
makinacorpus/goat-domain
. - Name normalization feature as been moved to the
makinacorpus/normalization
package. - New
makinacorpus/message
package now contains the shared message envelope and associated interfaces. - New
makinacorpus/event-store
package now contains the event store and the projector API. Please note that the project API itself might end up being deprecated if we don't have any new use case. - Lots of other dead code pieces will be trashed away.
- It will mostly remain only the command bus, dispatcher, message broker, event store and normalization API.
This will enter a state of bugfixes only, for our production projects still using it, but most of its code will progressively be deprecated in favor of new independant and more accurate packages:
- Existing
makinacorpus/corebus
package which is more or less the same as the dispatcher of this package, using more modern code and that is more extensively tested will eventually inherit from this dispatcher and message broker code.
Pre-requisites
Due to SQL RETURNING
clause usage, this cannot work with MySQL. This feature
is not SQL standard, but all of PostgreSQL, SQL Server and Oracle have a variant
of this feature, therefore could work with this package.
As of now, only PostgreSQL is an active target and have been tested with.
Features
- build a domain event driven model, derived from DDD and CQS with a message broken in the middle,
- provide an event store to save everything, and replay it.
Installation
composer req makinacorpus/goat-domain
Usage
Please document me.
Dispatcher
The Dispatcher is a component that behaves like symfony/messenger
component, it is the user facing interface for sending and consuming
messages from a bus.
It gives two methods:
-
an asynchronous message
dispatch()
, whose goal is to send messages to a message broker, -
a synchronous message
process()
whose goal is to consume messages and dispatch them to the correct message handler.
Base implementation comes down to:
dispatch()
just passes messages to a message broker,process()
just fetch a handler using an handler locator and executes it.
All other advanced features, including event store support are implemented using dispatcher interface decorators.
A console consumer command exists, it simply fetches messages from the message
broker and call dispatcher's dispatch()
method.
Event store
Introduction
The EventStore is a very primitive implementation of what you might use for implementing event sourcing. It saves all events that have been throught the applications into an ordered and immutable append-only log.
Every event that have been executed in the application will be saved into this journalisation mecanism.
It works the following way:
-
when a domain event is run through the dispatcher and processed synchronously the event is saved directly into the log, with the fail or success status along (a fail event is one that have been rollbacked),
-
when the messenger consumes an external or asynchronous message, it goes througth the dispatcher once again, and gets saved the way it has been written above.
Its usage is optional.
Some concepts
The event store allows to partially implement an event sourcing based system or it can be used a pure journalisation mecanism without being source of the actual data.
In both case, it will be plugged onto the message bus, and store every message
or domain event that happen to the system. For this to work gracefully, your
own events should implement the Goat\Dispatcher\Message\Message
interface in
order for the event store to be able to identify every aggregate or entity that
gets created or update within the system and keep track of objects life time.
It doesn't matter if you actually identify creation or modification, only a UUID is necessary, if it doesn't exist in the index, a new event stream will be created, if it exist a single event will append to the existing stream.
Advanced configuration
Please document me.
Monolog integration
Provide some extra options for monolog.
Please see the README.monolog.md file for more information.
Testing
A docker environement with various containers for various PHP versions is
present in the sys/
folder. For tests to work in all PHP versions, you
need to run composer update --prefer-lowest
otherwise PHP 7.4 tests will
fail.
composer install composer update --prefer-lowest cd sys/ ./docker-rebuild.sh # Run this only once ./docker-run.sh