Aller au contenu

Modèle de persistence


Command bus

Premier modèle utilisé dans MGX


  • Vient du modèle CQRS
  • Séparation du framework du code métier
  • Expression du besoin par une Command
  • Correspondance en interne au bus entre une Command et un Handler
    • tableau associatif constitué via le nom de la classe de la commande

function controller(CommandBus $commandBus, Repository $repository): Response
{
    $id = Id::new(Bannette::class);
    $commandBus(new Creer($id, 'Peu importe'));

    return new Response($repository->get($id)->expose());
}

Avantages

  • Interface simple
  • La Command ne contient que des données (pas de services)
  • Composable par des middlewares
    • flush de l'ORM
    • Envoi des tâches asynchrones planifiées
    • Envoi d'évènements dans Mixpanel

Inconvénients

  • Pas de donnée de retour à un appel au bus
    • la génération des ids doit être fait en amont dans le controller
  • Atomicité des Command qui empêche la composition des actions
    • si on a les commandes CreerBannette et ActiverOCR et qu'on veut que les 2 soient effectuées dans une même transaction alors il faut créer une 3° commande

Command bus version programmation fonctionnelle

Migration en cours (déjà utilisé dans MGSafe)


  • La notion de Command n'existe plus
    • Le tableau de correspondance disparait donc aussi
  • Le command bus n'est plus qu'un simple service qui fait
    • le flush de l'ORM
    • l'envoi des tâches asynchrones planifiées
  • Le service attend une callable sans argument

function controller(Persister $persister, Creer $créer): Response
{
    $bannette = $persister(fn() => $créer('Peu importe'));

    return new Response($bannette->expose());
}

function controller(
    Persister $persister,
    Creer $créer,
    ActiverOCR $activerOCR,
): Response {
    $bannette = $persister(function() use ($créer, $activerOCR) {
        $bannette = $créer('Peu importe');
        $activerOCR($bannette->id());

        return $bannette;
    });

    return new Response($bannette->expose());
}

Avantages

  • Moins de code car il n'y a plus l'indirection de la Command
    • Suppression de la magie qui créait le tableau de correspondance
  • On peut retourner des données
  • Composable car on peut appeler plusieurs services dans la callable

Inconvénients

  • On référence directement le service métier dans la couche framework
  • Utilisation systématique de fonctions anonymes

Différence annexe

Sur le tracking via mixpanel au lieu d'avoir une interface sur la Command c'est le service métier qui doit appeler maintenant le service de tracking dans son implémentation.