Adding a Service Layer to the Flux Architecture

Arran White
Developers Writing
Published in
2 min readSep 19, 2015

Something that became apparent over time as our React app grew in size and complexity was that our stores were becoming bloated and responsible for things that, in my opinion, did not belong there.

I’ll describe a really simple example up front so you can imagine exactly what I'm talking about:

A button component is clicked which triggers an action to add an item to a basket. If the basket is full then an alert should be raised to inform the user.

Typically the store will be listening for the ADD_TO_BASKET action and will then add the item to the basket if it is not full, else create an alert.
There are few things that bother me about this approach;

  1. The basket store is responsible for creating alerts.
  2. In my opinion, if an action is called, that action should be executed. If a condition is met that means item can’t be added, the action should not be called.
  3. Over time the store will become bloated as more logic is added.

Right, so the component should only call the action if there’s space in the basket?

// DON'T DO THIS.
/* ButtonComponent.js */
handleClick = () => {
if(BasketStore.isFull()) {
Actions.createAlert('Basket is full.');
} else {
Actions.addItemToBasket(item);
}
}

No no no, we just moved the business logic from the store to the component. The component now contains business logic and is responsible for creating alerts, not exactly reusable.

At least we only call the add to basket action if the basket has capacity so that’s a good thing. This code should not live in the component though, so where should it live?

In the Service Layer!

Let’s just look at some code.

/* ButtonComponent.js */handleClick = () => {
BasketService.addItemToBasket(item);
}
/* BasketService.js */addItemToBasket(item) {
if(BasketStore.isFull()) {
Actions.createAlert('Basket is full.');
} else {
Actions.addItemToBasket(item);
}
}

Awesome, why is this better?

  1. Actions do exactly what they say.
  2. Business logic is separated from the storage logic & view logic.
  3. Code is more maintainable as complexity increases.
  4. Helps to keep components reusable.

We have started putting all our business logic in the service layer and this has helped to keep our stores and components small and clean.

It’s also worth mentioning that services can be, and should be, created for things other than store abstractions. For example, all the logic for printing should live in a PrintService.

In closing, this is just my opinion and something that works for me right now. I would love to hear your opinions on this, hit me up on twitter — @arranwhite_.

--

--