somnambulist / read-models-bundle
Symfony integration for somnambulist/read-models
Installs: 2 001
Dependents: 1
Suggesters: 1
Security: 0
Stars: 1
Watchers: 4
Forks: 0
Open Issues: 0
Type:symfony-bundle
Requires
- php: >=8.1
- somnambulist/read-models: ^4.1
- symfony/framework-bundle: ^6.4|^7.0
Requires (Dev)
- doctrine/doctrine-bundle: ^2.11
- phpunit/phpunit: ^10.5
- somnambulist/domain: ^6.0
- symfony/dotenv: ^6.4
- symfony/messenger: ^6.4
- symfony/stopwatch: ^6.4
- symfony/var-dumper: ^6.4
- symfony/yaml: ^6.4
README
Integrates read-models into Symfony via a bundle.
Installation
Install using composer, or checkout / pull the files from github.com.
- composer require somnambulist/read-models-bundle
- add the bundle class to
config/bundles.php
as the last bundle- Note: if not configured last, then any custom doctrine types may not be assigned to the type caster as the Manager will boot too soon.
- add a config file (
config/packages/somnambulist.yaml
) with the configuration - map any custom casters via the
services.yaml
and tags - make some models
- load some data:
<model>::find()
An example config in config/packages/somnambulist.yaml
could be:
somnambulist_read_models: connections: 'default': 'doctrine.dbal.default_connection' 'App\Models\User': 'doctrine.dbal.user_connection' subscribers: request_manager_clearer: true messenger_manager_clearer: true
There are 2 event subscribers that are auto-registered:
- identity map clear on kernel request, terminate
- messenger clear on message handled / failed
If messenger is not installed, the listener will be disabled automatically.
Connections
Each model type can have a custom connection by using the fully qualified class name as the
key. When referencing the Doctrine connections, be sure to leave off the @
prefix if copying
from elsewhere.
Note that if the default is not specified, then the currently configured Doctrine default will be auto-registered.
Adding Attribute Casters
Add attribute casters as services and tag them with: somnambulist.read_models.type_caster
to have
them automatically registered with the Manager
s attribute caster instance.
To use the attribute-model
generic type casters, and them as services and configure as needed:
services: app.type_casters.some_service_identity: class: Somnambulist\Components\AttributeModel\TypeCasters\ExternalIdentityCaster arguments: $providerAttribute: 'some_service_name' $identityAttribute: 'some_service_id' $remove: true $types: - some_service_id tags: ['somnambulist.read_models.type_caster'] app.type_casters.my_value_object: class: Somnambulist\Components\AttributeModel\TypeCasters\SimpleValueObjectCaster arguments: $class: 'App\\Entities\\SomeEntityValueObject' $types: - short_name tags: ['somnambulist.read_models.type_caster']
Or if you don't need configuration, or have your own; use a resource:
services: App\TypeCasters\: resource: '../../src/TypeCasters/' tags: ['somnambulist.read_models.type_caster']
The attribute names should be the array key names that the values are expected to appear in from
the data source. For example: if a Product
model accesses a products
table that has unit_value
and unit_cur
fields, this could be converted to a Money
object by using the MoneyCaster
:
services: app.type_casters.product_money_caster: class: Somnambulist\Components\AttributeModel\TypeCasters\MoneyCaster arguments: $amtAttribute: 'unit_value' $curAttribute: 'unit_cur' $remove: true $types: - product_price tags: ['somnambulist.read_models.type_caster']
Then the caster can be referenced in the casts as: 'price' => 'product_price'
and the unit_value
and unit_cur attributes will be removed in favour of the single "price" attribute that will be a
Money value object. If the originals should be left in place, set $remove
to false
.
Additional casters can be added at any time; and existing casters may be overridden by re-using an existing type name however this is discouraged. Note that once a type is registered it cannot be removed.
Usage
See read-models for detailed docs on usage and attribute-models for more on the attribute caster.