/iso-call

Isomorphic call API or RPC as Promise for any nodejs/express application.

Primary LanguageJavaScriptOtherNOASSERTION

iso-call

Isomorphic call API or RPC as Promise for any nodejs/express application.

npm version Build Status Test Coverage Code Climate License

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

// For server side (in your main server script)
// Init ES2015 environments for require()
require('babel-core/register')();

// For client side (in your main client script)
// use iso-call polyfill wrapper. require babelify
require('iso-call/polyfill');

B. Polyfill way: for most case

// For both server side and client side
// require object.assign and es6-promise
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');

// Setup your API or RPC
isocall.addConfigs({
    // API as {name: endpoint} list
    yql: 'http://https://query.yahooapis.com/v1/public/yql',
    graph: 'https://graph.facebook.com/v2.3/641060562',

    // RPC as {name: function} list
    getSqlData: function (params) {
        return mysqlPromise(params.host, params.port);
    }

    // Also support RPC function with multiple parameters
    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!!

// Works on both client and server side!
isocall.execute('rpcName', rpcParams).then(function (R) {
    // Success, R = result
}).catch(function (E) {
    // Failed , E = error
});

// Support with multiple parameters rpc function
isocall.execute('rpcName', rpcParam1, rpcParam2, ...).then(function (R) {
    // Success, R = result
}).catch(function (E) {
    // Failed , E = error
});

Or make isomorphic http request!!

// Works on both client and server side!
isocall.request('apiName', requestParams).then(function (R) {
    // Success, R = {error: ... , response: ... , body: ...}
}).catch(function (R) {
    // Failed , R = {error: ... , response: ... , body: ...}
});

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.