3

Let's say my user requests my ES/CQRS system to open a support ticket:

  • The controller sends an ask-support command, this command checks if the user has enough credit to do that, then emits an asked-support event.

  • Somewhere, a listener responsible for side-effects gets this event. It calls an external support API to open a ticket and it retrieves a token from this call.

  • It sends an open-ticket command containing this token and this results in an opened-ticket event.

  • Now my controller should return the precious token to the client, but how?

With this publish/subscribe logic, my listener doesn't know the controller and can't tell him "hey, your ticket is created, here is your token".

I could have a read projection that results in a list of support tickets tokens and the controller could call it until the token appears (but that isn't great). Or somehow temporarily subscribe to the projection changes (but that's complex).

What strategy would you recommand for this case? Is my original design flawed?

Thanks

3

I'm not sure how you could prevent the asynchrony from propagating all the way to the client.

The controller could return a 201 Created immediately, along with the URI of the support ticket that has an Asked status at first. The client then polls the resource (automatically or from user initiative) to check its status until it becomes Opened and has a token.

  • 2
    So, in fact, you could prevent the asynchrony. You return a placeholder (the URI from 201 Created) for a value that will be provided at some later point in time... Which looks surprisingly like future-promise to me (over HTTP, but the idea stays the same). Good answer! – Mael Feb 16 '18 at 10:13
  • I meant, the asynchrony until the client lays its hands on the actual token ;) – guillaume31 Feb 16 '18 at 10:15
  • 1
    I kinda wanted to avoid polling but in fact this solution looks good, it's easily understandable and let me handle errors nicely, thanks – Thomas Lulé Feb 16 '18 at 11:18
1

You could assign your token to the request supplied by the controller, and return this. When the client asks "What is the status of request X?" it will hand you your token.

This approach has several useful properties. First, you can return the token immediately which is what you want. Second, you are not tied to the external API - when, for example, you will be switching to a different system and would like to migrate issues your tokens won't have to change.

The obvious downside is that you will have to map the external token to your internal one, but it's not a show-stopper IMO.

  • I can see how this can be useful but in my case the client needs the API token (I want to redirect the user to the external service using this token). So my real problem is to know when the API token is generated and my client can retrieve it. – Thomas Lulé Feb 16 '18 at 11:11
0

Provided that your framework supports async requests, if you know that opened-ticket will be fired at some point you can subscribe to it from within the controller action (using whatever infrastructure is available for accessing that event). Once a response is received you simply return the relevant information to the client.

  • oh this looks like my "subscribe to read projection" solution but easier! thanks, but i'm afraid this will become complex when I want to handle errors – Thomas Lulé Feb 16 '18 at 11:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.