I'm literally writing this to work through my thoughts, so I thought I'd share.
Framework: Angular + ngrx
Scenario: Your application is able to generate a particular type of report. Any user can run and see a summary of said report, but they need to pay x amount to see the whole thing.
Two things need to happen here:
- The user has to pay to unlock a particular report.
- If that transaction completes successfully, the report needs to be marked as "unlocked."
We could do all this sequentially. Make the payment API call, then make the unlock call. But that might involve duplicating some existing logic, and it might force me to create some awkward "payment + report" object.
We could also make one of those actions a side effect. But which one?
- is payment a "pre" side effect of unlocking the report?
- or is unlocking the report a "post" side effect of paying for the report?
The former seems to make more sense. The end goal is unlocking a report, not spending money, so let's say unlocking the report is the "main" control flow here.
But the payment must succeed for the report to be unlocked. So is it really a side effect? Shouldn't side effects should be independent of the thing that triggered them? Perhaps the side effect idea isn't so great.
<pause and think for a few minutes...>
Well, I have
@ngrx/effects. As much as I hate using it as an API wrapper (re Stop using ngrx/effects for that), it's a useful way to compose API calls from different services. Just because the library has "effects" in the name doesn't mean it has to be used strictly for side effects. We're certainly not restrciting it to that kind of usage right now. (Maybe in the future I should alias
@ngrx/effects with a different name so our particular usage makes more sense?)
I guess I'll do that. Use the existing payment logic, write an
unlock() service method, then use
@ngrx/effects to chain them together.
Inspired by DHH's "On Writing Software Well" video series