{"id":15699142,"url":"https://github.com/zordius/iso-call","last_synced_at":"2025-10-11T08:15:06.976Z","repository":{"id":30872695,"uuid":"34430333","full_name":"zordius/iso-call","owner":"zordius","description":"Isomorphic call API or RPC as Promise for any nodejs/express application.","archived":false,"fork":false,"pushed_at":"2017-12-05T07:18:36.000Z","size":91,"stargazers_count":6,"open_issues_count":2,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-14T19:45:17.775Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zordius.png","metadata":{"files":{"readme":"README.md","changelog":"HISTORY.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-04-23T03:00:51.000Z","updated_at":"2018-02-01T19:14:22.000Z","dependencies_parsed_at":"2022-09-13T18:31:59.090Z","dependency_job_id":null,"html_url":"https://github.com/zordius/iso-call","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zordius%2Fiso-call","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zordius%2Fiso-call/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zordius%2Fiso-call/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zordius%2Fiso-call/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zordius","download_url":"https://codeload.github.com/zordius/iso-call/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253176676,"owners_count":21866186,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-03T19:38:38.308Z","updated_at":"2025-10-11T08:15:01.938Z","avatar_url":"https://github.com/zordius.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"iso-call\n========\n\nIsomorphic call API or RPC as \u003ca href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise\"\u003ePromise\u003c/a\u003e for any nodejs/express application.\n\n[![npm version](https://img.shields.io/npm/v/iso-call.svg)](https://www.npmjs.org/package/iso-call) [![Build Status](https://travis-ci.org/zordius/iso-call.svg?branch=master)](https://travis-ci.org/zordius/iso-call) [![Test Coverage](https://codeclimate.com/github/zordius/iso-call/badges/coverage.svg)](https://codeclimate.com/github/zordius/iso-call) [![Code Climate](https://codeclimate.com/github/zordius/iso-call/badges/gpa.svg)](https://codeclimate.com/github/zordius/iso-call) [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE.txt)\n\nInstallation\n------------\n\n**Server**\n```sh\nnpm install iso-call express body-parser --save\n```\n\n**Client**\n\nA. Use \u003ca href=\"https://github.com/substack/node-browserify\"\u003ebrowserify\u003c/a\u003e + \u003ca href=\"https://github.com/benbria/aliasify\"\u003ealiasify\u003c/a\u003e to bundle your application and iso-call for browser:\n\n```sh\nnpm install browserify aliasify --save-dev\n```\n\nAdd these into your `package.json` to enable aliasify:\n\n```json\n  \"browserify\": {\n    \"transform\": [\"aliasify\"]\n  }\n```\n\nB. Use \u003ca href=\"https://github.com/webpack/webpack\"\u003ewebpack\u003c/a\u003e to bundle your applicatoin and iso-call for browser:\n\n```sh\nnpm install webpack --save-dev\n```\n\nAdd these into your `webpack.config.js` to make iso-call works properly:\n```javascript\n    resolve: {\n        alias: {\n            \"iso-call/polyfill\": \"babel-core/polyfill\",\n            request: 'browser-request'\n        }\n    }\n```\n\nUsage\n-----\n\n**1. Enable Required ES Features**\n\nYou should enable Promise and Object.assign() before using `iso-call` in your application for both server and client.\n\n*A. BABEL way: when you write ES2015 scripts*\n\n```javascript\n// For server side (in your main server script)\n// Init ES2015 environments for require()\nrequire('babel-core/register')();\n\n// For client side (in your main client script)\n// use iso-call polyfill wrapper. require babelify\nrequire('iso-call/polyfill');\n```\n\n*B. Polyfill way: for most case*\n\n```javascript\n// For both server side and client side\n// require object.assign and es6-promise\nrequire('object.assign').shim();\nrequire('es6-promise').polyfill();\n```\n\nYou may also enable polyfill for client side by including any polyfill web service in your HTML before loading bundled JavaScript file:\n\n```javascript\n\u003cscript src=\"https://cdn.polyfill.io/v1/polyfill.min.js\"\u003e\u003c/script\u003e\n\u003cscript src=\"bundle.js\"\u003e\u003c/script\u003e\n```\n\n**2. Setup your API**\n\nYou should setup all your API or RPC list only for server, the best place is do it inside your server.js.\n\n```javascript\nisocall = require('iso-call');\n\n// Setup your API or RPC\nisocall.addConfigs({\n    // API as {name: endpoint} list\n    yql: 'http://https://query.yahooapis.com/v1/public/yql',\n    graph: 'https://graph.facebook.com/v2.3/641060562',\n\n    // RPC as {name: function} list\n    getSqlData: function (params) {\n        return mysqlPromise(params.host, params.port);\n    }\n\n    // Also support RPC function with multiple parameters\n    getSQL: function (host, port, sql) {\n        return mysqlPromise(host, port, sql);\n    }\n\n});\n```\n\n**3. Setup middleware**\n\nYou should setup middleware for express only at server side to wrap client side `iso-call`.\n\n```javascript\nvar express = require('express');\nvar app = express();\n\nisocall.setupMiddleware(app);\n```\n\n**4. Call API or RPC!**\n\nNow you can call RPC isomorphically!!\n\n```javascript\n// Works on both client and server side!\nisocall.execute('rpcName', rpcParams).then(function (R) {\n    // Success, R = result\n}).catch(function (E) {\n    // Failed , E = error\n});\n\n// Support with multiple parameters rpc function\nisocall.execute('rpcName', rpcParam1, rpcParam2, ...).then(function (R) {\n    // Success, R = result\n}).catch(function (E) {\n    // Failed , E = error\n});\n\n```\n\nOr make isomorphic http request!!\n\n```javascript\n// Works on both client and server side!\nisocall.request('apiName', requestParams).then(function (R) {\n    // Success, R = {error: ... , response: ... , body: ...}\n}).catch(function (R) {\n    // Failed , R = {error: ... , response: ... , body: ...}\n});\n```\n\nHow it works?\n-------------\n\n**iso.execute() at Server side**\n* iso.execute() -\u003e getRPCFuncByName -\u003e execute -\u003e return Promise\n\n**iso.execute() at Client side**\n* iso.execute() -\u003e call wraped URL -\u003e middleware -\u003e getRPCFuncByName -\u003e execute -\u003e respone json -\u003e receive result -\u003e return Promise\n\n**iso.request() at both Server and Client side**\n* iso.request() -\u003e iso.execute(preDefinedRPCName, wrapedOpt)\n\nUse Case: isomorphic RPC\n------------------------\n\nCheck our \u003ca href=\"examples/01-shell\"\u003eshell example\u003c/a\u003e to know more about isocall.execute(). There is \u003ca href=\"examples/04-webpack\"\u003eanother example\u003c/a\u003e works by webpack.\n\nWith isocall.execute() a RPC you can:\n\n* Trigger server side only process with RPC then get the result from server or client side.\n* Place specific logic inside RPC to hide it from users.\n* Call API inside RPC to hide API endpoint from users.\n* Do input validation at server side to ensure security.\n* Reduce client side JavaScript size because RPC codes will not be bundled.\n\nUse Case: isomorphic http request\n---------------------------------\n\nCheck our \u003ca href=\"examples/02-yql\"\u003eYQL example\u003c/a\u003e to know more about isocall.request().\n\nWith isocall.request() an API you can:\n\n* Trigger an API by name from both server side and client.\n* Using consist options from \u003ca href=\"https://github.com/request/request\"\u003erequest\u003c/a\u003e.\n* Do not need to worry about cross domain request issue.\n\nUse Case: deal with request by context\n--------------------------------------\n\nCheckout our \u003ca href=\"examples/03-context\"\u003eContext example\u003c/a\u003e to know more about context based RPC which can access request by `this`.\n\nWith contexted isocall you can:\n\n* Access \u003ca href=\"http://expressjs.com/4x/api.html#req\"\u003eexpress request\u003c/a\u003e by `this` inside the RPC.\n* Do request based logic inside a RPC.\n* Get required cookie or headers from the request then pass to an API.\n\nUse Case: prevent CSRF\n----------------------\n\nCheckout our \u003ca href=\"examples/05-csrf\"\u003eCSRF example\u003c/a\u003e to know more about how to prevent \u003ca href=\"http://en.wikipedia.org/wiki/Cross-site_request_forgery\"\u003eCross-Site Request Forgery\u003c/a\u003e.\n\nNOTICE\n------\n\n* We use `JSON.stringify()` to transfer `isocall.execute()` result from server side to client side, so you can not receive data other than \u003ca href=\"http://www.tutorialspoint.com/json/json_data_types.htm\"\u003estandard JSON data types\u003c/a\u003e. (TODO: support customized JSON serializer)\n* 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`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzordius%2Fiso-call","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzordius%2Fiso-call","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzordius%2Fiso-call/lists"}