承接 jphooiveld/eventsauce-bundle 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

jphooiveld/eventsauce-bundle

Composer 安装命令:

composer require jphooiveld/eventsauce-bundle

包简介

EventSauce Bundle

README 文档

README

BUild status Scrutinizer Code Quality Code Coverage

Info

This bundle integrates EventSauce, and it's doctrine message repository into your symfony application.

It's strongly advised to know how EventSauce works or read up on the offical website (https://eventsauce.io) before you install this bundle.

Installation

Install the bundle into your symfony project.

$ composer require jphooiveld/eventsauce-bundle

Installing the bundle will give you an error because doctrine message repository is missing. You must install the doctrine message repository fromt the EventSauce project. Since the EventSauce project has a version for both Doctrine DBAL version 2.x and 3.x, it's impossible to use both at the same time, so you need to chooce the correct version yourself. The bundle will automatically check which version of the message repository is installed and load the appropriate services.

If you use a project Doctrine DBAL version 3.x. you must install the package.

$ composer require eventsauce/message-repository-for-doctrine

Or if you use a project with Doctrine DBAL version 2.x. you must install the package.

$ composer require eventsauce/message-repository-for-doctrine-v2

If you want to use symfony messenger as dispatcher instead of the default dispatcher you must install the package.

$ composer require symfony/messenger

If you want to use the console command to generate the database table for you, you must install the package.

$ composer require symfony/console

Normally symfony should be able to register the bundle automatically. If not you will need to add it to the bundles.php in your config directory.

<?php

return [
    Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
    Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
    Jphooiveld\Bundle\EventSauceBundle\JphooiveldEventSauceBundle::class => ['all' => true],
];

Configuration

jphooiveld_event_sauce:
    time_of_recording:
        # The timezone to use for recorded messages, defaults to PHP ini setting.
        timezone: UTC
    messenger:
        # Use symfony messenger instead of EventSauce's default dispatcher (needs package symfony/messenger installed).
        enabled: false
        # The name of the messenger command bus service to use.
        service_bus: messenger.bus.events
    message_repository:
        # Override if you don't want to use the default doctrine message repository but your own implementation. 
        # If doctrine is enabled this will be ignored.
        service: jphooiveld_eventsauce.message_repository.doctrine
        doctrine:
            # Use doctrine as default message repository. If you turn this off you must provide your own service.
            enabled: true
            # Service that implements a doctrine connection. We assume doctrine bundle default here.
            connection: doctrine.dbal.default_connection
            # The table name in the database to store the messages.
            table: event
            # JSON encode options for the doctrine message repository
            json_encode_options:
                - !php/const JSON_PRETTY_PRINT
                - !php/const JSON_PRESERVE_ZERO_FRACTION
            # Table schema to use: default (EventSauce 1.x) or legacy (EventSauce 0.8.x)  
            table_schema: default
            # UUID encpder to use: string or binary   
            uuid_encoder: string
        # Configure provided aggregate roots to use the default repository implementations as created by the bundle 
        aggregates:
            - App\Domain\Order
    snapshot_repository:
        # User snapshotting
        enabled: false
        # Service must point to a valid class that implements EventSauce\EventSourcing\Snapshotting\SnapshotRepository
        service: 'App\Infrastructure\MySnapshotRepository'
            

Configuration Detail

Messenger

By default, the synchronous message dispatcher from EventSauce is used. If you enable symfony messenger and provide the service id of the event bus all messages will be handled by the messenger component.

Message repository

The doctrine message component will automatically be installed as a dependency, otherwise there would be a non-functioning application. But if you want to install another type of repository or create your own it's easy to reference it in the service parameter. If doctrine is enabled (and it's by default) this will be ignored.

Configuring aggregates is an easy way to bind your aggregates to the message repository with default EventSauce services. A compiler pass creates the services automatically internally.

Lets for example assume you have an aggregate root called Order

<?php

namespace App\Domain;

use EventSauce\EventSourcing\AggregateRoot;

class Order implements AggregateRoot
{    
    // code
}

If you add 'App\Domain\Order' to the list of aggregates in the configuration the compiler pass will automatically create a service called jphooiveld_eventsauce.aggregate_repository.order. It will also create an argument binding named $orderRepository for interface EventSauce\EventSourcing\AggregateRootRepository for this repository so that you can inject it into your own services

Let's say we have a command handler that is responsible for persisting the order aggregate. We can now inject the order repository automatically for further use.

<?php

namespace App\CommandHandler;

use EventSauce\EventSourcing\AggregateRootRepository;

class AddOrderHandler
{
    public function __construct(
        private AggregateRootRepository $orderRepository,
    ) {
    }
    
    // other code
}

If you don't want to configure your repository then don't add it to the list and configue it yourself.

When snapshotting is enabled, and the snapshotting service points to a valid instance of EventSauce\EventSourcing\Snapshotting\SnapshotRepository every provided aggregate (under aggregates in message_repository configuration) that implements EventSauce\EventSourcing\Snapshotting\AggregateRootWithSnapshotting will automatically configure the message repository as well as the snapshot repository.

Auto configuration

EventSauce has a number of interfaces that are autoconfigured when this bundle is installed to make your life a lot easier.

Consumers

Consumers are responsible for handling events from the aggregates. The message dispatcher is responsible for delegating the events to the consumers. Every class you create and implements EventSauce\EventSourcing\MessageConsumer will automatically receive events from the message dispatcher. However, if you intend to use Symfony messenger you must implement the __invoke method. To overcome this limitation you can use the ConsumableTrait provided in the bundle. This will make sure it will work with the default message dispatcher from EventSauce as wel as the symfony messenger component. The trait will also let consumer's handler the events the same way as the aggregate repository does. It will look for methods that start with apply and after that the name of the event. Let's say we have a OrderCreated class which is an event that indicated ther order was created. Now we want to send an email notifcation. For example, we can create a listener as follows:

<?php

namespace App\Service;

use App\Event\OrderCreated;
use EventSauce\EventSourcing\MessageConsumer;
use Jphooiveld\Bundle\EventSauceBundle\ConsumableTrait;
use Symfony\Component\Mailer\MailerInterface
use Symfony\Component\Mime\RawMessage;

class SendMailNotification implements MessageConsumer
{
    use ConsumableTrait;
        
    public function __construct(
        private MailerInterface $mailer,
    ) {
    }
        
    protected function applyOrderCreated(OrderCreated $event): void
    {
        $message = new RawMessage(); 

        // other code
          
        $this->mailer->send($message);
    }
}

Whenever an order is created the method applyOrderCreated will be called.

Message decorators

Message decorators allow you to add extra headers to a message. Every class you create and implements EventSauce\EventSourcing\MessageDecorator will automatically add the headers that you define to the persisted message.

Upcasting

Upcasters can transform messages in case events change. Every class you create and implements EventSauce\EventSourcing\Upcasting\Upcaster will automatically be used.

Overriding default services

All services used in the bundles are actually aliases to real implementations. If you want to override services all you have to do is create your own services and override the aliases in the build method in your Kernel.

Beware that if you start to override services stuff can and will break because autoconfiguration uses a lot of the default implementations.

Alias Interface Breaks auto configuration
jphooiveld_eventsauce.clock EventSauce\Clock\Clock no
jphooiveld_eventsauce.payload_serializer EventSauce\EventSourcing\Serialization\PayloadSerializer no
jphooiveld_eventsauce.message_serializer EventSauce\EventSourcing\Serialization\MessageSerializer no
jphooiveld_eventsauce.upcaster EventSauce\EventSourcing\Upcasting\Upcaster yes
jphooiveld_eventsauce.inflector EventSauce\EventSourcing\ClassNameInflector no
jphooiveld_eventsauce.message_decorator EventSauce\EventSourcing\MessageDecorator yes
jphooiveld_eventsauce.message_dispatcher EventSauce\EventSourcing\MessageDispatcher yes

Let's say you want to create your own class inflector called App\EventSourcing\UnderscoreInflector that implements interface EventSauce\EventSourcing\ClassNameInflector. The only thing you need to do is set the alias in your kernel's build method and other dependent services will automatically use it.

<?php

namespace App;

use App\EventSourcing\UnderscoreInflector;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;

class Kernel extends BaseKernel
{
    protected function build(ContainerBuilder $container)
    {
        $container->setAlias('jphooiveld_eventsauce.inflector', UnderscoreInflector::class);
    }
    
    // other code
}

Upgrading from version 1.x

You must install the correct Doctrine Message Repository package from the EventSauce project when upgrading to version 2.x of this bundle.

A new option called table_schema has been added under the message_repository configuration. If you want to maintain backwards compatibility with your current database you will need to set it to legacy.

You can remove any bindings for aggregate repositories from your service configuration as the bundle already configures that for you in the compiler pass through the method registerAliasForArgument. See example below for our Order aggregate.

services:
    _defaults:
        bind:
            # Line below here is no longer needed, compiler pass will take care of it
            # EventSauce\EventSourcing\AggregateRootRepository $orderRepository: '@jphooiveld_eventsauce.aggregate_repository.order'

Some service configuration has changed. So if you have manually overriden anything you must check that configuration.

For upgrading your code EventSauce provides a rector package. See https://github.com/EventSaucePHP/RectorFrom0to1. Learn more about Rector at https://github.com/rectorphp/rector

License

This bundle is under the MIT license. See the complete license in the bundle.

jphooiveld/eventsauce-bundle 适用场景与选型建议

jphooiveld/eventsauce-bundle 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 50.91k 次下载、GitHub Stars 达 15, 最近一次更新时间为 2019 年 05 月 22 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「symfony」 「bundle」 「event sourcing」 「EventSauce」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 jphooiveld/eventsauce-bundle 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 jphooiveld/eventsauce-bundle 我们能提供哪些服务?
定制开发 / 二次开发

基于 jphooiveld/eventsauce-bundle 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 50.91k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 15
  • 点击次数: 21
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 15
  • Watchers: 3
  • Forks: 9
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2019-05-22