Redux Middleware for seamless REST communications.
Install using either npm
or yarn
:
npm install @rednetio/redux-rest-middleware
yarn add @rednetio/redux-rest-middleware
import { applyMiddleware, createStore } from 'redux';
import restMiddleware from '@rednetio/redux-rest-middleware';
const storeEnhancer = applyMiddleware(
restMiddleware({
base: 'http://localhost:3000',
authorization: getState => `Bearer ${getState().session.jwt}`,
}),
);
const store = createStore(reducer, initialState, storeEnhancer);
See the Meta properties section for more information.
const listTodos = () => ({
type: 'LIST_TODOS',
meta: {
rest: '/todos',
},
});
const reducer = (state = initialState, { type, payload }) => {
switch (type) {
case 'LIST_TODOS_REQUEST':
return {
...state,
loading: true,
error: null,
};
case 'LIST_TODOS_SUCCESS':
return {
...state,
todos: payload,
};
case 'LIST_TODOS_FAILURE':
return {
...state,
error: payload,
};
case 'LIST_TODOS_FINALLY':
return {
...state,
loading: false,
};
}
}
The restMiddleware
function takes an optional options
object that may
contain any of the following keys:
You must provide an authorization
function if you wish to use the
authenticated: true
(default) meta property. See the
Authentication section for more information.
Useful if you only ever hit one server: the base
will be concatened with your
meta rest
property to form the full endpoint. Defaults to ''
.
If you need to support older browsers or server-side rendering you’ll want to
provide a fetch
polyfill. Defaults to the global fetch
which is available
in modern browsers.
Either 'json'
, 'form'
or a custom encoding function that takes the payload
object and returns an object with stringified data
and a type
property for
the Content-Type
header. Defaults to 'json'
, which for reference is
implemented like this:
function encode(payload) {
return {
type: 'application/json',
data: JSON.stringify(payload),
};
}
Either 'json'
, 'form'
or a custom decoding function that takes the data
string and a type
(Content-Type
header) and returns an object. Defaults to
'json'
, which for reference is implemented like this:
function decode(data, type) {
if (type.indexOf('application/json') !== 0) {
throw new Error('Unsupported Content-Type');
}
return JSON.parse(data);
}
Provide an array if you want to have other action types. Defaults to
['_REQUEST', '_SUCCESS', '_FAILURE', '_FINALLY']
.
Wether to set an Authorization
request header or not. See the
Authentication section for more information. Defaults to
true
.
HTTP method. Defaults to GET
.
The REST endpoint you want to hit. Required.
Payload to send as the request body.
All requests are authenticated by default, which means the authorization
function will be called each time to provide an Authorization
request header.
You set the authorization
function in the middleware options. It takes a
getState
function as an argument, which returns the current state. You can
return:
- a string, which will be the
Authorization
header’s value, - a
{ header: value }
object to specify multiple or different headers (e.g.{ 'X-Token': 'value' }
), - alternatively, an array of
[header, value]
tuples to specify multiple or different headers (e.g.[['X-Token', 'value']]
), false
(the default) to disable authentication entirely. Note that this will throw an error wheneverauthenticated: true
is passed in a meta.
redux-rest-middleware
interfaces nicely with redux-actions.
See the redux-actions
example for details.