Read Models Bundle

Dave Redfern

Published: 21 Feb 01:22 in Symfony

Read-Models Bundle for Symfony

GitHub Actions Build Status

Integrates read-models into Symfony via a bundle.


Install using composer, or checkout / pull the files from

  • 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:

        'default': 'doctrine.dbal.default_connection'
        'App\Models\User': 'doctrine.dbal.user_connection'
        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.


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 Managers attribute caster instance.

To use the attribute-model generic type casters, and them as services and configure as needed:

        class: Somnambulist\Components\AttributeModel\TypeCasters\ExternalIdentityCaster
            $providerAttribute: 'some_service_name' 
            $identityAttribute: 'some_service_id'
            $remove: true 
        tags: ['somnambulist.read_models.type_caster']

        class: Somnambulist\Components\AttributeModel\TypeCasters\SimpleValueObjectCaster
            $class: 'App\\Entities\\SomeEntityValueObject' 
        tags: ['somnambulist.read_models.type_caster']

Or if you don't need configuration, or have your own; use a resource:

        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:

         class: Somnambulist\Components\AttributeModel\TypeCasters\MoneyCaster
             $amtAttribute: 'unit_value' 
             $curAttribute: 'unit_cur'
             $remove: true 
         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 infavour 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.


See read-models for detailed docs on usage and attribute-models for more on the attribute caster.

Return to article