Async XHR middleware for Redux
A light-weight middleware for Redux to do promise-based XHR requests. XHR headers and API gateway uri are configurable.
yarn add redux-xhr-middleware
import {createStore, applyMiddleware} from 'redux';
import xhrMiddlewareCreator from 'redux-xhr-middleware';
import rootReducer from '../myRouteReducer';
const createReduxStore = initialState => {
const xhrMiddleware = xhrMiddlewareCreator();
let enhancer = applyMiddleware(xhrMiddleware);
return createStore(
rootReducer,
initialState,
enhancer
);
};
const store = createReduxStore();
Your action creator needs to return an object with types
and xhr
properties, both must be provided.
const GET_AUTHORS_REQUEST = 'GET_AUTHORS_REQUEST';
const GET_AUTHORS_SUCCESS = 'GET_AUTHORS_SUCCESS';
const GET_AUTHORS_FAIL = 'GET_AUTHORS_FAIL';
const getAuthors = (authorId = '') => {
const url = siteId ? `/api/authors/${authorId}` : '/api/authors';
return {
types: [GET_AUTHORS_REQUEST, GET_AUTHORS_SUCCESS, GET_AUTHORS_FAIL],
xhr: {
url,
method: 'GET'
}
};
};
import merge from 'lodash/merge';
// ...
[GET_AUTHORS_REQUEST]: state => Object.assign({}, state, {
fetchError: null,
authors: [], // * see note below
isGetting: true
}),
[GET_AUTHORS_SUCCESS]: (state, {payload}) => merge({}, state, {
isGetting: false,
authors: payload // * see note below
}),
[GET_AUTHORS_FAIL]: (state, {payload}) => Object.assign({}, initialState, {
getError: payload,
isGetting: false
}),
// ...
// * note: If you use normalizr, you will not need to store entity data in these reducers,
// your dedicated 'entities' normalising reducer will keep that data.
You can specify an options object to the XHR middleware creator:
const options = {
apiHeaders: {},
apiGateway: ''
};
const xhrMiddleware = xhrMiddlewareCreator(options);
apiHeaders
can add/override any XHR header other than Accept
and Content-Type
headers, which are set as application/json
by default.
apiGateway
is a string as prefix to the paths, in case the API gateway is different to the application server, e.g. apiGateway
could be https://myGateway.com:8081
.
const options = {
apiHeaders: {
Authorization: 'my token'
},
apiGateway: '/api'
};
In your action creator, you can customise the HTTP header for your request.
const CREATE_AUTHORS_REQUEST = 'CREATE_AUTHORS_REQUEST';
const CREATE_AUTHORS_SUCCESS = 'CREATE_AUTHORS_SUCCESS';
const CREATE_AUTHORS_FAIL = 'CREATE_AUTHORS_FAIL';
const createAuthor = (payload) => {
const url = '/api/authors';
return {
types: [CREATE_AUTHORS_REQUEST, CREATE_AUTHORS_SUCCESS, CREATE_AUTHORS_FAIL],
xhr: {
url,
method: 'POST',
headers: {
'Accept': 'text/plain'
},
data: JSON.stringify(payload)
}
};
};