redux-superapi
generates actions and reducers for communicating with a REST backend. Its API is inspired from
redux-api, and it uses axios for making
the actual AJAX calls. Its goal is short, extensible and highly-readable code.
npm install --save redux-superapi
var superApi = new SuperApi(endPointsConfig, defaultRequestConfig = {})
Create a new SuperApi configuration.
endPointsConfig
(required): map unique endpoint names to an object with:url
(required): url of the endpointrequestKey
(optional): function that returns a unique identifier of the request. See making multiple requests for an endpointdefaultRequestConfig
(optional): default configuration passed on to axios, extending the configuration passed to theSuperApi
constructor.
defaultRequestConfig
(optional): pass a default request configuration that will be passed on to axios on every request.
Sample endpoint configuration:
const endpoints = {
experiments: {
url: "/api/experiments/"
},
experimentDetails: {
url: "/api/experiments/:experimentId/",
},
};
Next, create a store with the SuperApi reducers.
createStore(combineReducers(superApi.reducers));
Dispatch any of the following actions:
superApi.endpointName.get(args, requestConfig = {});
superApi.endpointName.getOnce(args, requestConfig = {});
superApi.endpointName.delete(args, requestConfig = {});
superApi.endpointName.head(args, requestConfig = {});
superApi.endpointName.options(args, requestConfig = {});
superApi.endpointName.post(args, data, requestConfig = {});
superApi.endpointName.put(args, data, requestConfig = {});
superApi.endpointName.patch(args, data, requestConfig = {});
superApi.endpointName.reset();
args
(required): dictionary mapping of arguments that need to be replaced in the URL.data
(required, only for post, put, patch): data to be passed to the serverrequestConfig
: configuration object passed on to axios. Extends the configuration set at the API/Endpoint levels.
Example: dispatch(superApi.experimentDetails.get({experimentId: 42}))
The getOnce
method will not trigger a new request if there is already a pending request or if data has already been
downloaded once.
The default state is:
{
[endpointName]: {
sync: false,
syncing: false,
loaded: false,
data: {},
error: null
}
}
dispatch
will always return a promise which you can chain with .then()
or .catch()
.
State's error
property will be axios' error message for malformed requests, or the data returned
by the end point if the request went through but returned a response with an error status code.
Since dispatch
returns a promise you can handle the error with dispatch(endPoint.get()).catch(...)
.
Dispatching superApi.endpointName.reset()
will not only reset the state, it will also cancel any request that was
started. Starting a new request will cancel any pending request automatically.
By default, you can only do one request at a time per endpoint. Doing another request will override the state and cancel the pending request. In some situations you actually want to be able to do multiple requests and store their state separately.
This is possible by defining the requestKey
endpoint option. requestKey
should be a deterministic function that
takes as sole argument a dictionary of the args
for the request and returns a string (or anything that can be cast to
string).
const endpoints = {
experimentDetails: {
url: "/api/experiments/:experimentId/",
requestKey: (args) => args.experimentId
},
};
The state will then look like
{
[endpointName]: {
[experimentId]: {
sync: false,
syncing: false,
loaded: false,
data: {},
error: null
}
}
}
There will be one separate entry for each different experimentId you call the API with, and they will all track their loading status and errors independently.
For cancelling a request simply pass the args
to reset
:
superApi.endpointName.reset({experimentId: 42})
A commonly used functionality is to transform the data received before saving it in the state. The best way to do this
is to pass a transformResponse
parameter to axios
.
const endpoints = {
experiments: {
url: "/api/experiments/",
defaultRequestConfig: {
transformRequest: [function (data) {
// Do whatever you want to transform the data
return data;
}],
}
},
};
Similarly, redux-superapi
doesn't implement any functionality that you can already configure with axios
so it is a
good idea to check out axios documentation.
Pull requests and issue reports are welcome.
Build:
npm run build
Test:
npm run test
Lint:
npm run lint
Copyright 2016 KAYAK Germany, GmbH
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.