Dom Kriskovic

@domagojk

Dispatch Redux actions as events, not commands!

May 15th 2017

Since I’ve mentioned it in the title, I guess you are familiar with Redux.
But did you know that this kind of architecture has been used in software development for more than twelve years now?

Actually, the idea itself is even older, but it was not until 2005 when Martin Fowler defined it as “event sourcing”.

Even though it’s not identical, Redux shares a lot of similarities with this model and I think there is still more we can learn from it.

In this post, I’ll describe the problem I faced and how it could’ve been avoided if I used event sourcing principles.

Using actions as events

In short, what I’m suggesting is using actions as events (facts describing what had happened) rather than commands which describes an intent of what should happen in the future.

I’m not the first person to suggest this or the first one that compared Redux with event sourcing.

Here are just a few resources describing similar ideas:

Undo/Redo

For more then three years I’ve worked as a lead frontend developer on a browser-based code editor.

Like any other editor it has a lot of features which can be used in different ways.

One example is: “undo/redo”.

Obviously, for this feature, the editor has to support Cmd+Z and Cmd+Y shortcuts, but there are many ways to invoke the same action:

  • Shortcuts (Cmd+ZCmd+Y)
  • Main Menu (Edit -> Undo, Edit -> Redo)
  • Toolbar (Undo/Redo icon)
  • GoTo Anything (“undo”, “redo” typed command)

So, I did what most of us would probably do:
Every time “undo/redo function” is requested, a component would dispatch an “UNDO” or “REDO” type action.

And this worked just fine.

But after a year or so, the company asked me if I could provide analytics on how our app is used. What actions are used in a toolbar, how does this relate to shortcuts etc?

Well, when you are working on a large scale app, these kind of tasks (which usually affect multiple teams) are probably not the most desirable ones.

Especially, when you don’t know much about event-driven architectures…

So, let’s just say I made some wrong decisions.

Event sourcing

What exactly can we learn from event sourced systems?

As the term “event sourcing” suggests — use events as your source of truth.

Rather than using a command “UNDO”, we can describe what actually happened:

“UNDO_SHORTCUT_INVOKED”
“UNDO_MAIN_MENU_ITEM_CLICKED”
“UNDO_TOOLBAR_ICON_CLICKED”
“UNDO_GOTO_ANYTHING_INVOKED”

If you don’t want to bloat your (or some other developer’s) reducers, you can also transform these actions in something with more generic type:

And we’re back where we started.

But now if your CEO wants you to generate analytics, you can do something like this:

What is a process manager?

This term is borrowed from CQRS/ES terminology where the same concept is also referred as “saga”:

a piece of code that coordinates and routes messages between bounded contexts and aggregates.

Redux middleware I used in these examples is one that I built myself — redux-orchestrate.

But you can also use more popular options like redux-saga or redux-observable.

Cons

Everything has its trade-offs, so here are some disadvantages you should consider:

  • Transforming actions requires middleware which has its own complexity
  • Dispatching more granular actions results in more messages that need to be handled

Event -> Process Manager -> Command concept may not apply to every use-case. It’s not a silver bullet solution and you should use it where it makes sense to you.

Conclusion

By using commands you are predicting the future.
This is problematic because you never know how your app will grow, how many people will work on it and what features should be implemented in the future.

By using events you are describing the past — facts which are always true and which can be used in ways you currently can’t imagine.

Events can be coordinated by a process manager which can handle side-effects and transform actions before they hit the reducer.

More by Dom Kriskovic

More Related Stories