PHP code example of etel / cqrs

1. Go to this page and download the library: Download etel/cqrs library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

etel / cqrs example snippets


use Symfony\Component\Messenger\Attribute\AsMessageHandler;
use Etel\CQRS\Command\AsCommandHandler;

#[AsCommandHandler] // library marker — tag handlers for your DI compiler pass
#[AsMessageHandler(bus: 'command.bus')] // Symfony Messenger routing
final readonly class CreateUserHandler { /* ... */ }

use Etel\CQRS\Command\CommandBus;

final readonly class CreateUser
{
    public function __construct(
        public string $email,
        public string $name
    ) {}
}

final readonly class CreateUserHandler
{
    public function __invoke(CreateUser $command): void
    {
        // ... persist ...
    }
}

// Dispatch — returns null, does not wait for a result.
$commandBus->command(command: new CreateUser(email: '[email protected]', name: 'Jane'));

use Etel\CQRS\Command\CommandResult;

#[CommandResult(CreatedUser::class)]
final readonly class CreateUser { /* ... */ }

$user = $commandBus->command(command: new CreateUser(/* ... */)); // $user is CreatedUser (statically + at runtime)

use Etel\CQRS\Query\QueryBus;
use Etel\CQRS\Query\QueryResult;

#[QueryResult(UserView::class)]
final readonly class GetUserById
{
    public function __construct(public int $id) {}
}

final readonly class GetUserByIdHandler
{
    public function __invoke(GetUserById $query): UserView
    {
        // ... load and return a UserView ...
    }
}

$user = $queryBus->query(query: new GetUserById(id: 42)); // $user is UserView

#[QueryResult(UserView::class, nullable: true)]
final readonly class FindUserByEmail
{
    public function __construct(public string $email) {}
}

$user = $queryBus->query(query: new FindUserByEmail(email: '[email protected]')); // UserView|null

use Etel\CQRS\Event\EventBus;

final readonly class UserRegistered
{
    public function __construct(public int $userId) {}
}

$eventBus->publish(event: new UserRegistered(userId: $user->id));

#[QueryResult(UserView::class)]                 // returns UserView
#[QueryResult(UserView::class, nullable: true)] // returns UserView|null
#[QueryResult]                                  // any result (scalar/array/union) — returns mixed

#[CommandResult(CreatedUser::class)]
final readonly class CreateUser { /* ... */ }

$created = $commandBus->command(command: new CreateUser(/* ... */)); // CreatedUser

// Force a typed result for a query you don't own:
$result = $queryBus->query(query: $thirdPartyQuery, expectResult: SomeResult::class); // SomeResult

// Commands accept true to mean "expect any result", false (default) for fire-and-forget:
$any = $commandBus->command(command: $command, expectResult: true);

use Etel\CQRS\Command\CommandInput;

/** @implements CommandInput<CreateUser> */
final readonly class CreateUserInput implements CommandInput
{
    public function __construct(
        public ?string $email = null,
        public ?string $name = null,
    ) {}

    public function toCommand(): CreateUser
    {
        if ($this->email === null || $this->name === null) {
            throw new InvalidCreateUserData(); // implements Etel\CQRS\Command\Exception\InvalidCommandData
        }

        return new CreateUser(email: $this->email, name: $this->name);
    }
}

// Dispatch the input; the middleware validates and transforms it into CreateUser.
$commandBus->command(command: new CreateUserInput(email: $request->email, name: $request->name));

use Etel\CQRS\Command\CommandBusOptions;
use Etel\CQRS\Query\QueryBusOptions;
use Etel\CQRS\Event\EventBusOptions;

// Command: delay (ms) and validation groups.
$commandBus->command(command: $command, options: new CommandBusOptions(
    delayMs: 5000,
    validationGroups: ['Default', 'strict']
));

// Query: validation groups only.
$user = $queryBus->query(query: $query, options: new QueryBusOptions(validationGroups: ['Default']));

// Event: delay and dispatch-after-current-bus.
$eventBus->publish(event: $event, options: new EventBusOptions(
    delayMs: 1000,
    dispatchAfterCurrentBus: true
));

use Etel\CQRS\Query\Exception\UnexpectedQueryResult;

try {
    $user = $queryBus->query(query: new GetUserById(42));
} catch (UnexpectedQueryResult $e) {
    // the handler returned something other than the declared UserView
}