daniellittledev/Enexure.MicroBus

Add interface for a command with result (ICommand<TResult>)

mjamro opened this issue · 3 comments

The library has IQuery<in TQuery, out TResult> interface.

There should be a similar version for commands that will allow for a result object ICommand<in TCommand, out TResult>. It should work in similar way as query does.

Purists will argue that commands must not return anything, but there are several good reasons for that:

  • it reduces complexity and simplifies your application, especially when you're not using eventual consistency nor client-generated ids.
  • This information will dramatically improve the user experience of your system, because you don’t have to poll an external source for command execution result, you have it right away. It becomes trivial to validate commands, and to return error messages.
  • If you want to refresh the displayed data, you can use the aggregate’s new version to determine whether the view model reflects the executed command or not. No more displaying stale data.

Example use cases:

  • Return information if record was deleted or not: public class DeleteFoo : ICommand<DeleteFoo, bool>
  • Return number of affected rows: public class DeleteFoos : ICommand<DeleteFoos, int>
  • Return new version number of your aggredate public class ChangeFoo : ICommand<ChangeFoo, int>
  • Return object containing more-verbose result of the operation: public class PerformComplexOperation: ICommand<PerformComplexOperation, OperationResult>
  • Return ID of created object in relational databases: public class CreateFoo: ICommand<CreateFoo, int>

See also: https://vladikk.com/2017/03/20/tackling-complexity-in-cqrs/

Hi @mjamro, this is something I can consider. I've found it useful to return a return type for failures and this change would enable that. However, I still feel that it would be worth encouraging users to not use commands for queries and limiting returned information, which I'm not sure how best to do. Encouraging patterns like Get-Post-Redirect instead of returning updated entities is one case I'd particularly like to discourage.

Is this issue something that you'd be willing to make a pull request for?

Sorry, i've been busy with different project (👶🏻)

Yes, i can prepare changes for this if it's free to take.

However, I still feel that it would be worth encouraging users to not use commands for queries and limiting returned information, which I'm not sure how best to do. Encouraging patterns like Get-Post-Redirect instead of returning updated entities is one case I'd particularly like to discourage.

I don't think there is a way of preventing people from doing stupid things. Documentation with explanation would have to suffice.

No worries at all, we're all busy doing something.

I haven't found the time yet either. So yeah, feel free to start a PR!