Redux has taken the web development by storm, and after the success of react and flux, it has made the flux philosophy more accessible through its simplified approach. Although, something has always bothered me about redux :

Why is it so complicated to call APIs?!

The async actions tutorial given in the documentation is no doubt a scalable approach to handling these kind of situations, but it’s not very simple, and you would need to go over it a couple of times before you get used to the idea. Sometimes, we need a simpler method for addressing API calls in apps that are not-so-complex.

This post will go through an alternative design pattern, to make async actions and API calls easier for smaller apps (and perhaps for larger ones as well), while respecting the three principles of redux and one way data flow.

Prerequisites

You should be comfortable with redux(and probably react) by now. An understanding of redux middleware would be nice, although it is not required (Just know that middleware is what comes in between dispatching an action and updating the store).

Our application

We are going to build on top of the redux to-do mvc example, by adding an API call to load the initial set of todo items.

The proposed pattern would make use of 4 steps for each API call :

Dispatch an action when the application needs to call an API. Render the application in a loading state for that particular API. Dispatch an action when a response is received. Render the application with the received data, or with an error message, depending on the response.

Adding an API service as a middleware

We will be adding a middleware which listens to all our actions, and calls an API when the appropriate action type is received. All actions, including actions recognized by this service should pass through the data service transparently, so that the rest of our application can still use them.

The normal flow of data in any flux architecture would look like this :

Adding our data service middleware would result in a slightly modified flowchart:

We create our API service in a single file :

import request from 'superagent' const dataService = store => next => action => { next ( action ) switch ( action . type ) { case 'GET_TODO_DATA' : request . get ( '/data/todo-data.json' ) . end ( ( err , res ) => { if ( err ) { return next ( { type : 'GET_TODO_DATA_ERROR' , err } ) } const data = JSON . parse ( res . text ) next ( { type : 'GET_TODO_DATA_RECEIVED' , data } ) } ) break default : break } } export default dataService

The data service we just created uses redux’s standard middleware signature. Also, we use the library superagent, an awesome HTTP library for making AJAX calls.