iso-call
Isomorphic call API or RPC as Promise for any nodejs/express application.
Installation
Server
npm install iso-call express body-parser --save
Client
A. Use browserify + aliasify to bundle your application and iso-call for browser:
npm install browserify aliasify --save-dev
Add these into your package.json
to enable aliasify:
"browserify": {
"transform": ["aliasify"]
}
B. Use webpack to bundle your applicatoin and iso-call for browser:
npm install webpack --save-dev
Add these into your webpack.config.js
to make iso-call works properly:
resolve: {
alias: {
"iso-call/polyfill": "babel-core/polyfill",
request: 'browser-request'
}
}
Usage
1. Enable Required ES Features
You should enable Promise and Object.assign() before using iso-call
in your application for both server and client.
A. BABEL way: when you write ES2015 scripts
require('babel-core/register')();
require('iso-call/polyfill');
B. Polyfill way: for most case
require('object.assign').shim();
require('es6-promise').polyfill();
You may also enable polyfill for client side by including any polyfill web service in your HTML before loading bundled JavaScript file:
<script src="https://cdn.polyfill.io/v1/polyfill.min.js"></script>
<script src="bundle.js"></script>
2. Setup your API
You should setup all your API or RPC list only for server, the best place is do it inside your server.js.
isocall = require('iso-call');
isocall.addConfigs({
yql: 'http://https://query.yahooapis.com/v1/public/yql',
graph: 'https://graph.facebook.com/v2.3/641060562',
getSqlData: function (params) {
return mysqlPromise(params.host, params.port);
}
getSQL: function (host, port, sql) {
return mysqlPromise(host, port, sql);
}
});
3. Setup middleware
You should setup middleware for express only at server side to wrap client side iso-call
.
var express = require('express');
var app = express();
isocall.setupMiddleware(app);
4. Call API or RPC!
Now you can call RPC isomorphically!!
isocall.execute('rpcName', rpcParams).then(function (R) {
}).catch(function (E) {
});
isocall.execute('rpcName', rpcParam1, rpcParam2, ...).then(function (R) {
}).catch(function (E) {
});
Or make isomorphic http request!!
isocall.request('apiName', requestParams).then(function (R) {
}).catch(function (R) {
});
How it works?
iso.execute() at Server side
- iso.execute() -> getRPCFuncByName -> execute -> return Promise
iso.execute() at Client side
- iso.execute() -> call wraped URL -> middleware -> getRPCFuncByName -> execute -> respone json -> receive result -> return Promise
iso.request() at both Server and Client side
- iso.request() -> iso.execute(preDefinedRPCName, wrapedOpt)
Use Case: isomorphic RPC
Check our shell example to know more about isocall.execute(). There is another example works by webpack.
With isocall.execute() a RPC you can:
- Trigger server side only process with RPC then get the result from server or client side.
- Place specific logic inside RPC to hide it from users.
- Call API inside RPC to hide API endpoint from users.
- Do input validation at server side to ensure security.
- Reduce client side JavaScript size because RPC codes will not be bundled.
Use Case: isomorphic http request
Check our YQL example to know more about isocall.request().
With isocall.request() an API you can:
- Trigger an API by name from both server side and client.
- Using consist options from request.
- Do not need to worry about cross domain request issue.
Use Case: deal with request by context
Checkout our Context example to know more about context based RPC which can access request by this
.
With contexted isocall you can:
- Access express request by
this
inside the RPC. - Do request based logic inside a RPC.
- Get required cookie or headers from the request then pass to an API.
Use Case: prevent CSRF
Checkout our CSRF example to know more about how to prevent Cross-Site Request Forgery.
NOTICE
- We use
JSON.stringify()
to transfer isocall.execute()
result from server side to client side, so you can not receive data other than standard JSON data types. (TODO: support customized JSON serializer) - The
result.response.body
object from isocall.request()
will be removed from result.response
to reduce transmission size; in most case it is same with result.body
.