Commands - To be explicit or not to be..

Since the discussions have been fired up on this group and I’m getting a huge amount of ideas and valuable feedback, I thought I’d throw another topic “in the mix” and see what happens.

The domain package in Axon Core currently contains two major domain concepts: the Aggregate and the Event. However, if I look back at my own workshops, I always talk about Commands, Aggregates and Events as being the building blocks for the “Core” of a CQRS application. Until now, the command was any POJO.

Now that the discussions on the Event are moving toward the Axon Event being a container for a POJO and some meta-data, I got the itch to do the same with the Command. The Command interface would provide access to the meta-data and the payload, which contains the application specific information.

The idea is that the @EventHandler and @CommandHandler annotated methods are allows to use the payload as parameter, as well as the entire Event or Command.

So my question to you is: should Axon 2.0 have an explicit command interface, or not?

Cheers,

Allard

Hi Allard,

Absolutely yes as long as payload is a Serializable VO and methods named dispatch on the CommandBus interface accept Serializable instead of Object.
This is the way that I'm using on my current project where the axon command bus is wrapped in a command service which is injected with a command meta-data provider (security and trasport infos) and trasport is backed by a JMS queue.
Regards
Domenico

Hello Allard,
It seems that it will be nice to have at least a marker interface for
Commands. Going a little bit further than that we can have a concrete
class for a Command with a strongly typed id inside, like you have in
an aggregate roots. Doing so will provide us an ability to enhance the
audit logging of commands by adding meta-information with command id
into the domain events. That in turn will make it easy to track what
command produced specific events.
Does it make sense to you?
Regards,Eugene

I'm a minimalist, so I guess my question is, what do I get for being
explicit? Right now I have no problems with my own class structure,
and with commands, aside from the bus and messaging, I'm not sure what
metadata would be required. Do we really need ID's for commands?
What does that gain us? Do we even need to serialize commands? I
think for the beginning user, there should be the ability to have
their own POJO's as commands, with the more complex solutions
requiring a class heirarchy to help deal with the infrastructure
concerns (messaging, idempotency, etc.)

Hi Chad,

it’s a good question. Maybe it doesn’t bring you a lot, but there are plenty of scenario’s where the payload of a command is not enough.

One example is auditing. By separating payload from meta-data, it is possible to attach meta-data to a command. The idea is to be able to correlate a command and the events generated from that command. This means (some or all) headers need to be copied to all events generated by a certain command. One of the systems here requires the executing userID to be attached to all generated events. When you use remoting, it’s useful to attach this information as the command’s meta-data.

In scaled systems, you might want to attach a routing ID (usually the aggregateType + aggregateIdentifier) to the command, so that systems can use consistent hashing to find the machine to forward the command to.

It is comparable to most messaging systems around, with the main difference that Axon distinguishes between commands and events.

Cheers,

Allard

Ahh ok, that makes sense. I haven't gotten to scaling my application
yet, so I haven't seen those problems. I do already have my own
metadata that I pass between commands and events (date, etc.). Were
you thinking something along the lines of a property lookup system,
e.g. a String, Object map? In order to make it powerful for the app
devs, you'll want to allow them to store their own metadata too.

Is there a balance to be made for the users who do not require
messaging layer infrastructure for their commands?

Example:

public interface Command {

    Object getMetadata(String key);

}

public abstract class SimpleCommand {
    private Map<String, Object> metadata = new HashMap<String,

();

   public Object getMetadata(String key) {
        return metadata.get(key);
    }

    protected void putInMetadata(String key, Object stuff) {
        metadata.put(key, stuff);
    }

}

public abstract class MessagingCommand<I> implements Command {

    I getId();
    ... metadata to be implemented per messaging system ...
}

public interface CommandBus<C extends Command> {

    void doStuff(C command);

}

public class SimpleCommandBus implements CommandBus<Command> {
    public void doStuff(Command command) { ... }
}

public abstract class MessagingCommandBus<I, C extends
MessagingCommand<I>> implements CommandBus<C> {

    void routeMessage(I id, C);
}

With a two pronged approach (simple singlethreaded, and message based,
where the different message providers would have their own
implementation), you can KISS for the newbies and non-scaled apps,
while still providing the more complex approach and leave it up to the
app dev as to which path to take. The caveat to this situation would
be you would want to limit the Command interface to as few methods as
possible (or even an empty interface to maintain the plain POJO route
for simple apps).

Make sense?

The idea of meta-data is absolutely that apps can add their own. Axon doesn’t need much to process the commands. I’ve built multiple applications using Axon, and so have some colleagues, and sooner or later, I noticed that each application has some sort of meta-data on commands.

It’ll be lightweight anyway. You can create a command by doing: new GenericCommand(myPayload); or new GenericCommand(myPayload, myMetaData); The meta-data is effectively a key Map<String, Object>.

For more advanced features, you could think of special command implementations, such as RoutableCommand, which sets specific meta data values needed by a routing command bus.
Spring Integration uses a similar approach, btw.

Cheers,

Allard

Yeah, I actually was iterating that after I posted and thought of the
abstract instances ala RoutableCommand which define a subset of
functionality and clearly communicate intent (DDD for the framework
objects :slight_smile: I look forward to seeing what you've come up with. Also,
with the payloading, how do you plan on implementing the different
deserializers, or is that left to the command implementation? Do you
have any of it in github yet?

Chad

I’m still refactoring the Event payload part. It’s quite a big chunk to chew. As soon as that’s done, I’ll commit it. Next up is probably the command.

Cheers,

Allard

Hi Allard, Chad,

a few lines just to share my point of view, hoping not to bore you or sound too biased, although I must admit that my vision on the subject is heavily influenced by the context in which i happily use axon framework.

  1. When we talk about command and metadata are we talking about the same thing? I think not, because, although the latter are related to the first, they represent different aspects of data that may come from different sources, they represent different purposes and often must be handled in a different manner. E.g. authorization and audit metadata usually come from a different layer and may require special handling (different transactional semantics, different datasource etc.).

  2. Properly building the object that contains the payload and metadata can be a non-trivial task for the client even in the presence of a command builder. Some required metadata may be difficult to find or not available to the client at the time of creation. E.g. the security context could not be accessed by the client issuing the command, the IP address of the host running the command, in a distributed environment, is known only after its delivery and so on. Certainly we don’t want to entrust the responsibility of application orthogonal aspects to the client.

That said I am more inclined to consider this kind of metadata (audit, routing etc.) as attributes of the message that carries the payload rather than the command itself. So I think that the task of enriching command with metadata should be assigned to the bus, which will delegate to others, and let the client ignores everything that happens in this regard.

Cheers

Domenico

Thanks Domenico. Well said! I was going to express the same exact
concern, but you explained it perfectly.

I think if we change the API of the command-bus and instead
an Axon-independent construct, expect to get an Axon-defined
construct to be passed to the event bus, we get into the same
problem that the events currently have and we are trying to
fix it.

Essentially the commands need to carry two parts; the payload,
namely the command from the Axon-user point of view; and
the user's metadata, which is nothing more than a Java Map
from String to Object. Although they are both owned by
Axon-users, they may be formed totally independently and
in different locations.

If the above is correct, can't we just add an optional argument
to the command-bus's API as well as the command-handler's API
for passing an extra Java Map<String,Object> containing the
user's metadata? And no other changes?

This way if an application doesn't need the metadata, it can
pass null to the command-bus, and receive null on its
command-handlers. No Axon dependency on the command-bus's
API. This is similar to the UOW formed internally by the
Axon and passed optionally to the command-handlers.

Regards,
Esfand