Skip to content

[Not a bug] When to use ICommand vs IRequest? Docs say differently from the code examples? #1875

Closed

Description

@jeffward01

Hello all!

This library is excellent!!! Very clean, easy to use and powerful!

I am confused on when to use ICommand vs IRequest

The code and documentation says IRequest is a base class of IEvent and ICommand. That is great. I assume when you want to be more explicit and ensure your Command is only processed by command handlers and not Event Handlers you would use ICommand, and when you want to be more loose about it, you could use IRequest?

Here is the only part in the documentation where it speaks about this: https://paramore.readthedocs.io/en/latest/DispatchingARequest.html#using-the-base-class-when-dispatching-a-message

From the source code:

I am confused, because if I understand this correctly, the docs are telling us to use ICommand or IEvent, rather than IRequest.

However, in all of the code examples in the documentation, IRequest is used. From looking at the code, it appears IRequest is what you would want to use, however the documentation makes me think that I should not use IReqest

Can someone please clarify what is best practice for this? Thanks!

Activity

  1. preardon commented on Nov 30, 2021

    @preardon
    Member

    Hi @jeffward01

    IEvent and ICommand are the correct ones to use, when you are using an external bus it needs to map to one of these two types to dispatch the messages. I would recommend being explicit and selecting one or the other, I assume at the minute you are only dispatching internally (CommandProcessor.Send) as such if I had to guess most of what you are doing should be ICommand (I personally just use Command)

    For further clarification the way I define the difference between a Command and an Event is, a Command is a request to do something (i.e. Create new Order) and an Event is a notification to say something has been done (i.e. NewOrderVersionCreated)

    I hope this helps, I am going to tag @iancooper in as he is the expert here and can point out anyvhere that I may have missed something out / add more detail

  2. iancooper commented on Dec 1, 2021

    @iancooper
    Member

    Command - expects only one handler - an instruction for work
    Event - zero or more handlers - an observable fact
    Request - base class, a message that I want to handle, could be a command or event

    But @preardon is right

  3. jeffward01 commented on Dec 8, 2021

    @jeffward01
    Author

    You both read my mind! sorry for the slow reply. @preardon @iancooper

    I assume at the minute you are only dispatching internally (CommandProcessor.Send) as such if I had to guess most of what you are doing should be ICommand (I personally just use Command)

    Exactly, just testing internally, I am thinking for my architecture I plan to use Brigher / Darker for in-process and CAP for out-process.

    Question 1
    The main reason for this is that CAP has an NATS integration. I know this is the Brigher repo, but am I making a mistake by not leveraging Brighter for out-process items? Do you have any example handlers I can examine so that I can easily implement NATS for Brighter?

    For further clarification the way I define the difference between a Command and an Event is, a Command is a request to do something (i.e. Create new Order) and an Event is a notification to say something has been done (i.e. NewOrderVersionCreated)

    Question 2
    This is very helpful! So in theroy, is this 'good practice:

    API Endpoint POST --> Handler (ICommand) --> The handler then calls a second .Publish method which goes to --> Handler (IEvent) ....

    I think what I am trying to ask in question 2 is "Is it bad practice to have "Handlers" call other "Handlers", or should this be handled with listening events such as the Mediatr INotification event?

    Question 3

    I feel improper opening up an issue to discuss these FAQ questions, is there a better place I can go in the future for these questions?

    Final Notes

    Event is a notification to say something has been done (i.e. NewOrderVersionCreated) - @preardon
    Event - zero or more handlers - an observable fact - @iancooper

    This is very helpful! For example I was thinking that the IEvent class functioned a little bit like INotification from Mediatr or Azure Event Grid, which is basically "Hello everyone! We have a new order received event, go take your places and take care of it" and signals the rest of the application to 'do work'.

    But in Brighter, its a confirmation event, which is much more like DDD. Thanks for clarifying this!! I appreciate it very much!!!

    Thank you again for the help!! you guys are great

  4. preardon commented on Dec 8, 2021

    @preardon
    Member

    1: one of the best examples to follow for implementing a Messaging Transport for brighter is the RMQ one, there are only a few interfaces that need to be implemented and should be fairly straightforward

    2: Firstly for out of proc messaging please use Deposit / DepositPost these use the outbox pattern, also if you want your outbox to participate in the same transaction as your database you will have to use DepositPost. Send and Publish are for in proc works.

    The question I would ask here is why is a handler calling another handler, I have many command handler that create events or even other commands i.e.

    API post (new Order)-> ICommand (Create new order) -> creates Event (NevOrderVersionEvent>

    Or even

    API post -> ICommand (start Batch job) -> chunks batch job and create a command for each

    The only thing I would say about the batch job route is that we don't yet support bulk but I'm hoping this will be a v9.next feature

    3: There is the discussions tab on GitHub but the main thing is that this is somewhere where others can see and benefit from it

  5. iancooper commented on Dec 8, 2021

    @iancooper
    Member

    The main reason for this is that CAP has an NATS integration. I know this is the Brigher repo, but am I making a mistake by not leveraging Brighter for out-process items? Do you have any example handlers I can examine so that I can easily implement NATS for Brighter?

    We have an issue, #1208 and I was planning on tackling in the 9.x timescale. If you feel up to it, you could have a stab. But if you are happy to help test it, I could probably pick up that issue over the weekend and create an alpha version of NATS for you. You might find it easier to PR fixes for that than write from scratch. It was on my ToDo list anyway

  6. iancooper commented on Dec 8, 2021

    @iancooper
    Member

    API Endpoint POST --> Handler (ICommand) --> The handler then calls a second .Publish method which goes to --> Handler (IEvent) ....

    Yes, that it how it tends to be done.

  7. iancooper commented on Dec 8, 2021

    @iancooper
    Member

    ?3: There is the discussions tab on GitHub but the main thing is that this is somewhere where others can see and benefit from it

    Indeed, we care about folks being able to find answers, and are happy to answer questions. We can move this issue into discussions, but let's work through the conversation first

  8. jeffward01 commented on Dec 8, 2021

    @jeffward01
    Author

    Thanks guys for being so helpful with all of this, its been super helpful and lightening fast reply times are something that I can aspire to haha.

    My replies:

    Question 1.)

    1: one of the best examples to follow for implementing a Messaging Transport for brighter is the RMQ one, there are only a few interfaces that need to be implemented and should be fairly straightforward

    We have an issue, #1208 and I was planning on tackling in the 9.x timescale. If you feel up to it, you could have a stab.

    Big thanks on sharing the #1208 issue link! I found the code here for RMQ Messaging Transport. I'd love to take a stab at it and let you guys know how it goes, despite my questions i'm a pretty competent developer, all my code is on Azure DevOps, which makes my github is rather sparse. I am looking forward to learning more about brighter and the inner workings!

    What attracted me to brighter was how clean it was, and how similar it was to Mediatr, but with multiple very important 'power-up' features like out-process messaging queues. When I look at CAP, it appears CAP only does out-of-process messaging while Brighter does in and out of process messaging. (not sure if this is accurate for CAP, but pretty sure it is)

    Question 2.)

    Thanks, this makes alot of sense, basically just add a 'listener' handler which waits for the IEvent which will be called by the first handler. Perfect!

    Firstly for out of proc messaging please use Deposit / DepositPost these use the outbox pattern

    ^^ Thank you for mentioning these and pointing me in the right direction!

    Question 3.)

    Big thanks for the clarification, personally I think its best on the Issues area, rather than discussions. I tend to check Issues more often rather than the discussion area, but I know that the discussion area is built for this. Wherever you decide to put it works for me. I will start to check the discussions area.


    Last question on the topic, (i'll open a new topic if I have further questions because my original question was 100% answered)

    I plan to take a stab at #1208 - I am rather new to Brighter codebase, and I just wanted to ask you guys this question to see if my understanding is correct. I will also try and answer my own question and you can see if im on-target or not.

    Question 4 (final)
    If CAP already implements NATS, what is the advantage to using Brighter? Why would a developer select the Brigher / Darker package over CAPS / MediatR combo.

    Jeff's Answer:

    Brighter provides both the familiar style of MediatR while also including out-of-process messaging patterns (including outbox) for out-of-proc communication for things such as Microservices. A developer will choose brighter / darker when looking for a messaging library which can do it all (in / out) without additional bells and whistles required. Instead of being dependent on CAP to do the logging and errors logging (I think this is bad practice as it fragments away from the logging / error infrastructure already in place), with Brighter it makes the developers use their own logging infrastructure

    • MediatR is only 'in-process'
    • CAP is only 'out-process' AND provides a new syntax which varies a good amount from the classic MediatR

    The only real advantages (feature wise) CAP would have over Brighter / Darker at this current point in time (roadmap not included) would be:

    • The UI dashboard similar to hangfire of events and messages (this is what the CAP storage section is about)
    • some diagnostic details using Apache Skywalking SkyAPM
    • a few more Message Transports (a developer can implement these yourself or wait for the roadmap)

    Thanks guys for your patience with my on this! I'll give #1208 a go! it'll take me a few days to spin-up on it, I have a few dependencies I have to take care of first on some other projects I am working on. I need NATS integration for my final implementation so I certainly will work on it asap <3

  9. iancooper commented on Dec 8, 2021

    @iancooper
    Member

    'd love to take a stab at it and let you guys know how it goes,
    Awesome. We like it when folks who are using something in anger step up to work on the relevant transport - reach out if you need help. I'll assign #1208 to you.

    Jeff's Answer:
    That seems a pretty solid evaluation

  10. iancooper commented on Dec 12, 2021

    @iancooper
    Member

    Going to move this to a discusion

  11. locked and limited conversation to collaborators on Dec 12, 2021
  12. converted this issue into a discussion #1889 on Dec 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions