How to get data back from a command bus? How to get data back from a command bus? php php

How to get data back from a command bus?


First, notice that if we wire the controller directly to the command handler, we face a similar problem:

    public function createPost($req, $resp)    {        $command = new CreatePostCommand($command->getTitle(), $command->getContent());        $this->createPostCommandHandler->handle($command);        // How do we get the data of our newly created post to the response here?        return $resp;    }

The bus is introducing a layer of indirection, allowing you to decouple the controller from the event handler, but the problem you are running into is more fundamental.

I'm not sure how to proceed with this problem from here

TL;DR - tell the domain what identifiers to use, rather than asking the domain what identifier was used.

    public function createPost($req, $resp)    {        // TADA        $command = new CreatePostCommand($req->getPostId()                 , $command->getTitle(), $command->getContent());        $this->createPostCommandHandler->handle($command);        // happy path: redirect the client to the correct url        $this->redirectTo($resp, $postId)    }

In short, the client, rather than the domain model or the persistence layer, owns the responsibility of generating the id of the new entity. The application component can read the identifier in the command itself, and use that to coordinate the next state transition.

The application, in this implementation, is simply translating the message from the DTO representation to the domain representation.

An alternative implementation uses the command identifier, and derives from that command the identities that will be used

        $command = new CreatePostCommand(                 $this->createPostId($req->getMessageId())                 , $command->getTitle(), $command->getContent());

Named UUIDs are a common choice in the latter case; they are deterministic, and have small collision probabilities.

Now, that answer is something of a cheat -- we've really only demonstrated that we don't need a result from the command handler in this case.

In general, we would prefer to have one; Post/Redirect/Get is a good idiom to use for updating the domain model, but when the client gets the resource, we want to make sure they are getting a version that includes the edits they just made.

If your reads and writes are using the same book of record, this isn't a problem -- whatever you read is always the most recent version available.

However, is a common architectural pattern in domain driven design, in which case the write model (handling the post) will redirect to the read model -- which is usually publishing stale data. So you may want to include a minimum version in the get request, so that the handler knows to refresh its stale cache.

Is there an elegant way to return the post's data in the response?

There's an example in the code sample you provided with your question:

public function createPost($req, $resp)

Think about it: $req is a representation of the http request message, which is roughly analogous to your command, and $resp is essentially a handle to a data structure that you can write your result into.

In other words, pass a callback or a result handle with your command, and let the command handler fill in the details.

Of course, that depends on your bus supporting callbacks; not guaranteed.

Another possibility, which doesn't require changing the signature of your command handler, is to arrange that the controller subscribes to events published by the command handler. You coordinate a correlation id between the command and the event, and use that to pull up the result event that you need.

The specifics don't matter very much -- the event generated when processing the command could be written to a message bus, or copied into a mailbox, or....


I am using this approach and I am returning command results. However, this is a solution which works only if the command handlers are part of the same process. Basically, I'm using a mediator, the controller and the command handler get an instance of it (usually as a constructor dependency).

Pseudo code controller

var cmd= new MyCommand();var listener=mediator.GetListener(cmd.Id);bus.Send(cmd);//wait until we get a result or timeoutvar result=listener.Wait();return result;

Pseudo code command handler function

var result= new CommandResult();add some data heremediator.Add(result,cmd.Id);

That's how you get immediate feedback. However, this shouldn't be used to implement a business process.

Btw, this has nothing to do with DDD, it's basically a message driven CQS approach which can be and it is used in a DDD app.