Redux api middleware that runs promises to fetch data from an api endpoint.
Table of Contents
- Getting Started
- ApiRoutes
- Actions
- connect(apiRoutes)
- getRequest(filters, apiOptions) => action
- fetchEntity([id, filters, apiOptions]) => action
- fetchList([filters, apiOptions]) => action
- fetchPage([filters, apiOptions]) => action
- fetchNextPage([filters, apiOptions]) => action
- saveEntity(attributes[, filters, apiOptions]) => action
- deleteEntity(attributes[, filters, apiOptions]) => action
- saveList(ids, attributes[, filters, apiOptions]) => action
- deleteList(ids, [, filters, apiOptions]) => action
- ApiOptions
- Reducers
- Contributing
- Versioning
Getting Started
Installation
Install the @drieam/api and
its dependencies.
yarn add @drieam/api @drieam/common
Usage
import * as api from '@drieam/api';
import { setStore } from '@drieam/common';
type API = {
user: models.canvas.user;
};
type Store = RootReducer<{
api: api.reducers.Connect<API>;
}>;
const api: ApiRoutes<API> = {
user: {
path: '/lti/proxy/api/v1/users/:id?',
mapper: models.canvas.User,
list: true,
options: {
onError,
}
},
};
const actions = api.actions.connect<API>(api);
const rootReducer = api.reducers.connect<API>(api);
const store = setStore(
api,
rootReducer,
[],
,
)({
});
ApiRoutes
Routing Structure is base of a key-value object where you can configure your basic reducer structure for use cases where you need to fetch data from Rest APIs.
This structure is base on a type and a Hash object from that type.
The API type is a reference between your resource and the class used by the middleware to instantiate it.
path
apiRoute.path: PathtoRegExp | (params) => string
Turn a path string into a regular expression. (More info)
mapper
apiRoute.mapper: class | (data) => any;
The model class to be instantiated by the middleware. It can be a generic class or custom.
list
apiRoute.list: boolean | reducer;
As true sets the base ListState reducer but you can pass a custom reducer.
entity
apiRoute.entity: boolean | reducer;
As true sets the base EntityState reducer but you can pass a custom reducer base on that one.
options
See More on ApiOptions
Note: Whether list
or entity
should be defined. If both are not defined or false, redux
will complaint with an error.
Actions
connect(apiRoutes)
const actions = api.actions.connect<API>(api);
Creates an object
structure with all the redux actions needed for each resource definition.
getRequest(filters, apiOptions) => action
actions.user.getRequest({ includes: 'users' });
Creates a request action depending of the filter properties:
- default parameters is FETCH_LIST
- filters.page is present then FETCH_PAGE
- filters[rowKey='id'] is present then FETCH_ENTITY
fetchEntity([id, filters, apiOptions]) => action
actions.user.fetchEntity(1);
Creates an action to fetch an entity object.
fetchList([filters, apiOptions]) => action
actions.user.fetchList();
Creates an action to fech a collection of entities.
This action refresh the data in the reducer.
fetchPage([filters, apiOptions]) => action
actions.user.fetchPage({ page: 3});
Creates an action to fetch a page of a entity object collection. This page is added in the reducer.
fetchNextPage([filters, apiOptions]) => action
actions.user.fetchNextPage();
Creates an action to fetch the next page of a entity object collection.
saveEntity(attributes[, filters, apiOptions]) => action
actions.user.saveEntity(user);
Creates an action which saves or updates an entity object.
deleteEntity(attributes[, filters, apiOptions]) => action
actions.user.deleteEntity(user);
Creates an action to delete an entity object.
saveList(ids, attributes[, filters, apiOptions]) => action
actions.user.saveList([1, 2], user);
Creates an action which updates a collection of entity objects. The attributes
can be one or many and it will be update per id position.
deleteList(ids, [, filters, apiOptions]) => action
actions.user.deleteList([1, 3]);
Creates an action which delete a collection of entity objects.
ApiOptions
Settings of an action.
{
rowKey: 'id',
csrfToken: null,
updateMethod: 'PUT',
credentials: 'same-origin',
nestedPayloadKeySuffix: 'Attributes',
headers: {},
onSuccess: undefined,
onError: undefined,
}
rowKey
apiOptions.rowKey = string
Row's unique key
csrfToken
apiOptions.csrfToken = string
Cross-site request forgery token.
insert
apiOptions.insert: string = 'prepend'
Order of insertion a listState. default: 'append'
updateMethod
apiOptions.updateMethod: string = 'PUT'
Set the default udate method to PUT
or PATCH
credentials
apiOptions.credentials: omit | same-origin | include = 'same-origin'
Set the default udate method to PUT
or PATCH
The request credentials you want to use for the request: omit
, same-origin
, or include
. To automatically send cookies for the current domain, this option must be provided.
nestedPayloadKeySuffix
apiOptions.nestedPayloadKeySuffix: string = 'Attributes'
A string to transform the collection name before sending.
apiOptions.headers: object = {}
HTTP headers allow the client and the server to pass additional information with the request or the response. An HTTP header consists of its case-insensitive name.
form
apiOptions.form: 'redux-form' | null = 'redux-form'
Return a specific reduxForm SubmissionError on Error.
onSuccess()
apiOptions.onSuccess: (data: T) => void;
Callback made by the middleware when a api call is successful.
onError()
apiOptions.onError: (error: ErrorResponse) => void;
Callback made by the middleware when an error occurs.
Reducers
connect(apiRoutes)
const apiReducers = api.reducers.connect<API>(api);
Creates an object
structure with all the redux actions needed for each resource definition.
apiReducers..list
Redux Store of a collection of fetched entities.
Example
{
pending: boolean = false
fulfilled: boolean = false
rejected: boolean; = false
settled: boolean; = false
value: T[] | null = null
reason: string;
errors: [{
code: number
message: string
errors: {}
}];
status: number;
links: {
next?: {
page: number,
url: srting,
},
last?: HeaderLink
first?:HeaderLink
prev?:HeaderLink
};
perPage: number;
count: number;
filters: QueryParams;
}
apiReducers..entity
Redux Store of a fetched entity.
Example
{
pending: boolean = false
fulfilled: boolean = false
rejected: boolean; = false
settled: boolean; = false
value: T | null = null
reason: string = null
status: number = null
}
Contributing
We welcome all contributors who abide by our Code of Conduct. Please see the Contributors Guide for more details on submitting a PR, setting up a local dev environment, running tests, etc...
Versioning
Until this project reaches a 1.0 milestone, minor version numbers will simply be incremented during each release. The Changelog will continue to document the different types of updates, including any "breaking changes".
After the 1.0 milestone, this project will follow SemVer.