Redux API Middleware (Fixed Fork)
raw JSON →redux-api-middleware-fixed is a Redux middleware designed for declarative API calls. It intercepts specific Redux Standard API-calling Actions (RSAAs), identified by a `[CALL_API]` property, and dispatches Flux Standard Actions (FSAs) during the request lifecycle (request, success, failure). This package is a community-maintained fork, currently at version 2.0.0, addressing outstanding pull requests and maintaining the original `redux-api-middleware` codebase. Its primary differentiator is providing a consistent, action-based pattern for managing API side effects within a Redux application, simplifying data fetching and error handling by abstracting away the boilerplate often associated with `fetch` or `axios` calls within Redux thunks or sagas. The release cadence appears infrequent, primarily driven by maintenance needs rather than active feature development.
Common errors
error TypeError: 'CALL_API' is not a symbol ↓
CALL_API directly from redux-api-middleware-fixed and using it as the action key without attempting to cast it as a Symbol if it's not. For example, [CALL_API]: { ... } is correct. error Error: Middleware argument must be a function. Expected an object with a 'type' property. ↓
applyMiddleware(apiMiddleware) is correctly set up in your Redux store configuration. Also, double-check that your dispatched action includes [CALL_API] as a property, and that the object assigned to [CALL_API] has endpoint, method, and types properties. error Unhandled Rejection (TypeError): Failed to fetch ↓
Warnings
breaking The original `redux-api-middleware` used `Symbol('CALL_API')` as the action key. This 'fixed' fork, specifically around v1.2.0, introduced changes that might treat `CALL_API` as a string instead of a Symbol. While this can simplify serialization, it might break existing code relying on Symbol comparison or strict type checks if migrating from older versions of the original package. ↓
gotcha This package is a fork. While it aims to fix issues, it may not receive updates or new features at the same pace as actively maintained alternatives or the original project (if it were still maintained). Long-term maintenance and compatibility with future Redux versions are less certain. ↓
gotcha The middleware dispatches Flux Standard Actions (FSAs). Ensure your reducers are designed to handle actions with `type`, `payload`, and `error` properties as defined by the FSA specification. Non-FSA compliant actions might lead to unexpected behavior in reducers. ↓
gotcha Error handling for API calls defaults to an `ApiError` object in the `payload` when `error: true` is set. If not handled correctly, UI might not display meaningful error messages or application state might not reflect the error condition. ↓
Install
npm install redux-api-middleware-fixed yarn add redux-api-middleware-fixed pnpm add redux-api-middleware-fixed Imports
- apiMiddleware wrong
const apiMiddleware = require('redux-api-middleware-fixed').apiMiddleware;correctimport { apiMiddleware } from 'redux-api-middleware-fixed'; - CALL_API wrong
const CALL_API = require('redux-api-middleware-fixed').CALL_API;correctimport { CALL_API } from 'redux-api-middleware-fixed'; - isRSAA wrong
import isRSAA from 'redux-api-middleware-fixed/lib/isRSAA';correctimport { isRSAA } from 'redux-api-middleware-fixed';
Quickstart
import { createStore, applyMiddleware, combineReducers } from 'redux';
import { apiMiddleware, CALL_API } from 'redux-api-middleware-fixed';
// A dummy reducer
const dataReducer = (state = { loading: false, users: [], error: null }, action) => {
switch (action.type) {
case 'FETCH_USERS_REQUEST':
return { ...state, loading: true, error: null };
case 'FETCH_USERS_SUCCESS':
return { ...state, loading: false, users: action.payload.users };
case 'FETCH_USERS_FAILURE':
return { ...state, loading: false, error: action.payload, users: [] };
default:
return state;
}
};
const rootReducer = combineReducers({
data: dataReducer
});
// Configure the Redux store with apiMiddleware
const store = createStore(rootReducer, applyMiddleware(apiMiddleware));
// Define an API call action
const fetchUsers = () => ({
[CALL_API]: {
endpoint: 'https://jsonplaceholder.typicode.com/users',
method: 'GET',
types: ['FETCH_USERS_REQUEST', 'FETCH_USERS_SUCCESS', 'FETCH_USERS_FAILURE']
}
});
// Dispatch the action
store.dispatch(fetchUsers());
// You can subscribe to store changes to see the state updates
const unsubscribe = store.subscribe(() => {
console.log('Current state:', store.getState().data);
});
// In a real application, you'd typically handle errors and unmount subscriptions
// setTimeout(() => unsubscribe(), 5000);