Skip to content

Make SubscriberUtil obsolete and remove it #743

@DanielBadura

Description

@DanielBadura

We already talked once about this and I still think this trait should be removed but the neat functionality should stay.

Right now my projections are looking like this:

#[Projector('public_profile_v5')]
final class PublicProfileProjection implements PetProfileRepository
{
    use SubscriberUtil;

    private readonly string $tableName;

    public function __construct(
        private readonly Connection $projectionConnection,
    ) {
        $this->tableName = 'projection_' . $this->subscriberId();
    }

    #[Setup]
    public function create(): void
    {
        $table = new Table($this->tableName);
        // ...
     }

     // ....
}

First, the #[Projector] needs the id so that the subscription engine can work. Next, i want to reuse this id so that i dont need to duplicate the string and to be sure, that this tablename is not already in use by another projection since the id must be unique. Third, I prefix it with projection_ for better maintainability if the DB is shared with e.g. an ORM. To achieve this, we introduced the SubscriberUtil trait, which enables us to have access on the SubscriberHelper in a DX friendly way.

So what's the problem? First, I think to provide API's over traits is not a good design decision. Second it is not really clear on the first glance how the table is named. Third analysing this statically is unnecessary complex, i tried to use https://github.com/staabm/phpstan-dba in one of my projection which can only operate if the tablenames are constant strings. And i think this extension could be really useful when working with small tailored projections since it may be that you can drop the dto layer, as the types / shapes can be inferred statically.

So i thought we could again have a look on this and I can think about this like that:

#[Projector]
final class PublicProfileProjection implements PetProfileRepository
{
    #[Id]
    private const TABLE_NAME = 'projection_public_profile_v5';

    public function __construct(
        private readonly Connection $projectionConnection,
    ) {
    }

    #[Setup]
    public function create(): void
    {
        $table = new Table(self::TABLE_NAME);
        // ...
     }

     // ....
}

So making the id optional on the subsriber attribute, and if not set, try to look out for an #[Id] attribute placed on a const or maybe property. This would basically only require a change in AttributeSubscriberMetadataFactory, would make the SubscriberUtil useless, tablename would be more intuitive to read and statically analysable.

We could reuse again the #[Id] attribute as we already did for commands and queries, but maybe we should add something else since this time we are not talking about an aggregate id.

What do you think about this idea?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions