cattle-bridge v0.1.3
Cattle Bridge
./README_CN.md
for translation.
About Cattle Bridge
Cattle Bridge is a further encapsulation of network request operations that fits the actual application requirement. In the actual application, the seperation of front-end and back-end is widely used. However, the data returned by network requests often requires further processing before it can be used for front-end logic. For example, front-end developers might agree:
/* Return API data - an example of the common structure */
{
"status": 2200, // Various status code for APIs
"error_msg": "OK",
"data": { // Useful data returned by APIs.
"some field": "",
// some other data ...
},
"extra_info": {},
}
This means that the front-end developers have to process each group of data offered by APIs, using the same code. When dealing with many APIs, these processes might be distributed throughout the whole project's files. And when the basic appointments are changed, maintenance could be a nightmare. Cattle Bridge can process the data from the input-or-output interface according to the given rules, as a reault, redundant codes could be eliminated.
Install
Use NPM
- Install
npm install cattle-bridge -s
- Import when needed. As an UMD module it supports both ES6
import
and CommonJSrequire
.
import CattleBridge from 'cattle-bridge'; // ES6
const CattleBridge = require('cattle-bridge'); // CommonJS
Install and build manually
git clone
this repository.- Execute command:
npm run build
- Then, a UMD module file would be created in
./dist
. - Import when needed. The UMD module supports both ES6
import
and CommonJSrequire
Quick Start
A primary example
const CattleBridge = require('./cattle-bridge.umd.js');
const axios = require('axios');
const filters = {
bindDevice: {
method: 'POST',
url: '/user_device/bind',
chop: inp => ({ // Do some handling before submited to the network requester.
code: inp.deviceId,
}),
trim: rep => ({
result: !!rep.success, // Do some handling for data returned by network.
}),
},
updateUserInfo: {
url: '/user_info',
method: 'POST',
chop: inp => ({
name: inp.name,
height: inp.height,
weight: inp.weight,
birthday: inp.birth,
gender: inp.gender,
profession: inp.job,
emotion: inp.marriage,
}),
},
};
const stater = function (result, respData, respStat, currentFilter) {
if (respStat.status !== 200) {
result(false);
return {
code: -1,
msg: 'HTTP Error',
friMsg: 'Cannot connect to the servers.',
};
} else {
result(respData.status == 0);
return {
code: respData.status,
msg: respData.error_msg,
friMsg: mapToFriendlyMessage(respData.status),
};
}
}
const apier = new CattleBridge({
debug: true,
stater,
filters,
requester: axios,
gtrim: rep => resp.data || {},
});
With the assistance of the configuration above, you can operate like the following now:
apier.fetch('bindDevice', {deviceId: 10001})
.then(() => {
// The interface tell you task has been done
console.log('The operation is done.');
}, ({data, stat}) => {
// The interface is failed
console.log('Some error happend!');
console.log('Error Code: ', stat.code);
console.log('Tips: ', stat.friMsg);
});
It is obvious that a pretty simple object is inputed as data for this request.
{ deviceId: 10001 }
The input data is processed before passed to axios.
{ code: 10001 }
Data returned by network responses is a bit complex.
{
status: 2200,
error_msg: 'OK',
data: { success: 1 },
}
After processed by Cattle Bridge, the parameters received by your .then
callback are as follows. The processed data is placed in the data
key. So concise.
{
data: { result: true },
stat: {
code: 2200,
msg: "OK",
friMsg: "Your operation has been done!",
},
}
Maybe sometimes the operation of the API request failed. Error codes and error descriptions are attached to interface responses content.
{
status: 4400,
error_msg: 'too many requests',
data: { success: 0 },
}
In this case, the callback function passed into .catch
will receive:
{
data: { result: false },
stat: {
code: 4400,
msg: "too many requests",
friMsg: "Please wait for a minute and then try again", // Friendly error message.
},
}
So, Cattle Bridge can automatically proceed each network request according to configured rules. It is concise to call a network request and data received is easier to read and operate. Moreover, .then
and .catch
are called according to whether the API has a successive operating result or not - although both them are '200 OK' in the view of HTTP response.
The above is a short but clear example. Cattle Bridge also offers more features and greater flexibility. Please read this document further to explore what else Cattle Bridge can do.
API Reference
Constructor new CattleBridge(options)
{
debug: boolean, // false
stater: function , // required
requester: function,// required
gchop: function, // optional
gtrim: function, // optional
filters: // filter list
}
- debug: true to print debug console messages.
- stater: a function to generate state information.
- requester: a function used to send network requests. Compatible with axios API.
- gchop: global chop processor.
- gtrim: global trim processor.
- filters: an object including several filters.
filters
An object including several filters. Each item has the interface call name as its key and the filter object as its value. The interface call name should be passed to .fetch
method as its first parameters to use the corresponding filter or interface.
gchop
Global chop handler. It is used to proceed data after the current filter's chop handler.
Refer to the description of filter.chop
in the next section.
trim
Global trim handler. It is used to proceed data before the current filter's trim handler.
Refer to the description of filter.trim
in the next section.
stater
A function used to compute a state value for a response and return, which would be passed into request callbacks - both successive callback (.then) and failure callback (.catch).
Refer to .fetch
method for more information.
4 parameters are avaliable.
The first parameter is a callback function that must be called to mark this response as a successive response or a fail one.
const stater = function (result, respData, respStat, currentFilter) {
result(true); // The interface has finished asked operations successively.
// Mark this response as a successive one to continue the next steps.
// - OR -
result(false); // The interface has not finished operations correctly.
// Mark this response as a failure to continue the next steps.
}
Neither callback (.then
/.catch
) will be called if the result-marking function is not called.
requester
Network requester, a function that can send network requests. It should be compatible with the basic API of axios, which means axios can be directly applied to this item.
{
// ...
requester: require('axios'),
// Or other functions compatible with axios' API.
// ...
}
filter
Filter
is a key option given as an object that tells Cattle Bridge how to proceed input and output data. Each interface is proceeded according to the corresponding filter.
{ // Option overlook
name: String, // (optional) filter name, used in console debug outputs.
url: Function, // Network request URL
method: , // HTTP method
chop: Function | Array[Function], // The handler for request input data
trim: Function | Array[Function], // The handler for response output data
request: Function | any, // Parameters accepted by the requester.
handler: Function, // The customised handler for request, which operates
// independently and return the response.
}
name
optional filter name, used in console debug outputs to make them more readable.
chop
and gchop
A function or a array constituted by functions.
The functions accept inp
as data inputed by calling .fetch
and return data
to be sent to network, which is corresponding to options.data
in axios' options.
When using a function array, the input data of a function is what returned by the previous function. The first function in the array accepts data inputed by calling .fetch
and the return value of the last function is used as requester's options.data
.
filter.gchop
is same as being attached to the end of all of chops.
trim
and gtrim
A function or a array constituted by functions.
The function accepts network response data as its input (axios' response.data
) and returns output data passed to Promise callback (then/catch).
When using a function array, the input data of a function is what returned by the previous function. The first function in the array accepts network response data as input data and the return value of the last function is used as a part in parameters of callbacks (then/catch).
Assigned filter.gtrim
is equal to be attached to the beginning of trims。
request: Function | Object
request
can be a function or an object.
Using an object, its return value is passed into requester as the network request options. Using a function, it accepts input data (proceeded by chops) as a parameter and returns an option object accepted by the requester.
Refer to axios' API documents to find out the details of the option object.
request(inp)
url & method
optional url : Network request URL
optional method : HTTP request method
The two fields are sweets, whose effects are same as the assigned requset.url
or requset.method
.
Using a function, input data would be passed into this function as the only parameter, and set its return value to requester's corresponding field. A given constant value would directly become requester's corresponding fields.
Priority and coverage between different fields
The network request parameter values are covered when various options are given.
chop / trim
have the highest priority. request
is the second. url / method
are less prior.
For example, if both chop
and request
are assigned at the same time, the value given by data
field in request
is covered by the value given by chop
. Similarly, if the request
option is assigned and it offers method
fields, the method
value assigned in filter option object would be rewrite.
handler
: more flexibility allowed
Sometimes, it is not enough to just rely on allowed options offered by Cattle Bridge. Use handler
option in the filter option object for more precise control in this case.
handler
is a function accepting several parameters.
filter.handler(resolve, reject, name, input)
Parameters | |
---|---|
resolve | Same as resolve in Promise |
reject | Same as reject in Promise |
name | Request interface name offered to .fetch method. |
input | Interface input data offered to .fetch method. |
handler
offers a way to generate and process more complex requests or responses.
You might have the familiar feelings if you often write Promise instances. A successful or failed callback is made by calling resolve
or reject
where needed. Parameters passed into resolve
or reject
are passed directly to the fetch#then
or fetch#catch
callbacks. The parameters passed in need not conform to the form of {data,stat}
just like demo code in this document, various values are okay as long as there is no problem in the corresponding callback of the fetch#then
or fetch#catch
.
Start a request
Start some network requests after configuration.
Now, you should have a instance of Cattle Bridge, whose .fetch
method is used to construct a new request.
#fetch
accepts two parameters, request interface name and input data. It returns a Promise instance whose .then
and .catch
are used to handle the resolved and rejected states.
The functions passed to .then
or .catch
accept an object including data
as response output data and stat
as interface request state information.
It is worth noticing that data
is the return value from trim
function and stat
is the return value from assigned stater
function. The two functions and their return values are designed and provided by users themselves, which would not be read or modified by Cattle Bridge.
{
data: '', // Any value, any data type are acceptable .
stat: ,
}
Below is a simple example.
var CattleBridge = new CattleBridge(options);
CattleBridge.fetch('ImplementName', inputData)
.then(({data, stat}) => {
// Tips: destructuring assignment used in function parameters
// Succcess handler <=> Promise resolve
}).catch(({data, stat}) => {
// Error handler <=> Promise reject
}))
Using other HTTP request libraries
Cattle Bridge is designed according to the axios' API, which means you can use axios
directly as Cattle Bridge's requester
parameter, without additional configuration.
import axios from 'axios';
var CattleBridge = new CattleBridge({
...,
requester: axios, // That works!
...
})
However, axios is not available in some cases, for example, a special JavaScript runtime whose network request APIs are designed particularly or some conditions where other AJAX libraries are compulsory.
Anyhow, just a requester that conforms to the axios API can drive Cattle Bridge (encapsulating is easy, generally speaking). Cattle Bridge makes no assumptions about the network request APIs in the runtime environment. It just plays a role as middle layers.