Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feedback from commandhandler #36

Open
r3dsm0k3 opened this issue Jul 18, 2019 · 5 comments
Open

Feedback from commandhandler #36

r3dsm0k3 opened this issue Jul 18, 2019 · 5 comments

Comments

@r3dsm0k3
Copy link

First of all, thank you for your effort in creating a neat library and ecosystem around it.

I was wondering if there is a way already built in to handle errors in handling a command.
My api layer may send a command via the bus . Value objects are created and validated before constructing the command itself, but there may be infrastructural errors which prevents from the command to get fulfilled successfully. How do you get the command handler to send a message back to the caller that my command has failed? Currently I'm using the command handler directly in my api layer (handler.handle(MyCommand)) which is not ideal, especially since I already use the bus .

I could perhaps subscribe to the events which are produced by the commands, but that introduces bad user experience (because there's no immediate feedback) and complicates even further imo.

So in short, is there a way to handle a command synchronously and wait for its output?

What I could imagine is the following.

try {
  const result = await this.bus.send(myCommand) 
  // the result should contain the outcome from the successful invocation of the command
} catch(e) {
 if(e.constructor === InfrastructorError) {
  // handle things
 } else { 
  // handle everything else
 }
}

Thanks and looking forward to your suggestions.

@adenhertog
Copy link
Contributor

Hey Ajith,

I think here you're talking about the request-response pattern of EIP messaging, ie: https://www.enterpriseintegrationpatterns.com/patterns/conversation/RequestResponse.html. This library has currently only implemented a pub-sub style so there's no way to await a bus-based response directly.

Implementing something like this wouldn't be too difficult and using it would be pretty similar to your example.

There may be an alternative depending on what's requesting your API. If your consumer is a web front end, would it be feasible to subscribe the resulting event via a websocket?

@r3dsm0k3
Copy link
Author

Hi @adenhertog , thanks for the quick response.
I'm building a graphql api, which maybe consumed by web frontends or desktop applications or mobile apps. In this case, I'm registering a user and there's no way to respond with an error/registered user's uuid. We'd have to have another query for this. As I said, I currently work around this with not using the commandbus, but instead calling the commandhandler directly. From the library I'm only using the eventbus and the DDD modules. It would be really great if I could use all the features if there was a work around.

How about handing in an optional callback function along with the .send() ? It could get triggered after all the registered handlers have finished processing the message and bus can invoke it.

@adenhertog
Copy link
Contributor

Hi @r3dsm0k3

Thanks for your feedback. Your current workaround is probably the simplest, though it does bypass the bus entirely. When using it, the library needs to be agnostic around its environment. The problem when trying to invoke a callback when the command finishes comes down to not being guaranteed where the command gets executed.

The command handler could be on another instance of the API, or could be sitting in a separate application service. In theses cases your command would leave the current node, traverse the message transport, be processed at some point (depending on the load of your message handling service) and an event/reply emitted.

Once the event is emitted, there's no way to ensure that the originating API instance will be the one who receives it - at least not in a pub/sub style setup. One way to achieve this is to enhance the library to support private ephemeral queues and enable a replyToSender() function. This would allow a command handler to directly send a response to the sender of the command by placing the response in the sender's private queue.

The idea of a callback passed into send() would work fine for a single-instance of a memory-queue, but the ultimate goal of this library is to provide the same functionality regardless of the size or setup of the underlying services.

I'll use this ticket to track .replyToSender() and .replyTo() functionality

@psaunders
Copy link

psaunders commented Aug 6, 2019

@adenhertog this would be awesome, I'm building a very API centric tool so it'd expand the places I can use this from a bit of the deep backend to almost all of it.

@manarhusrieh
Copy link
Contributor

Recently, I have applied a similar approach using Web sockets with the service bus. The command handler at the end of its execution would send a message through web socket and the API would wait for this message from web socket to resolve the promise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants