Package Exports
- json-rpc-2.0
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (json-rpc-2.0) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
json-rpc-2.0
Let your client and server talk over function calls under JSON-RPC 2.0 spec.
- Protocol agnostic
- Use over HTTP, WebSocket, TCP, UDP, inter-process, whatever else
- Easy migration from HTTP to WebSocket, for example
- Use over HTTP, WebSocket, TCP, UDP, inter-process, whatever else
- No external dependencies
- Keep your package small
- Stay away from dependency hell
- First-class TypeScript support
- Written in TypeScript
Install
npm install --save json-rpc-2.0
Example
The example uses HTTP for communication protocol, but it can be anything.
Server
const express = require("express");
const bodyParser = require("body-parser");
const { JSONRPCServer } = require("json-rpc-2.0");
const server = new JSONRPCServer();
// First parameter is a method name.
// Second parameter is a method itself.
// A method takes JSON-RPC params and returns a result.
// It can also return a promise of the result.
server.addMethod("echo", ({ text }) => text);
server.addMethod("log", ({ message }) => console.log(message));
const app = express();
app.use(bodyParser.json());
app.post("/json-rpc", (req, res) => {
const jsonRPCRequest = req.body;
// server.receive takes a JSON-RPC request and returns a promise of a JSON-RPC response.
server.receive(jsonRPCRequest).then(jsonRPCResponse => {
if (jsonRPCResponse) {
res.json(jsonRPCResponse);
} else {
// If response is absent, it was a JSON-RPC notification method.
// Respond with no content status (204).
res.sendStatus(204);
}
});
});
app.listen(80);
With authentication
To hook authentication into the API, inject custom params:
const server = new JSONRPCServer();
// If the method is a higher-order function (a function that returns a function),
// it will pass the custom parameter to the returned function.
// Use this to inject whatever information that method needs outside the regular JSON-RPC request.
server.addMethod("echo", ({ text }) => ({ userID }) => `${userID} said ${text}`);
app.post("/json-rpc", (req, res) => {
const jsonRPCRequest = req.body;
const userID = getUserID(req);
// server.receive takes an optional second parameter.
// The parameter will be injected to the JSON-RPC method if it was a higher-order function.
server.receive(jsonRPCRequest, { userID }).then(jsonRPCResponse => {
if (jsonRPCResponse) {
res.json(jsonRPCResponse);
} else {
res.sendStatus(204);
}
});
});
const getUserID = (req) => // Do whatever to get user ID out of the request
Client
import { JSONRPCClient, createJSONRPCErrorResponse } from "json-rpc-2.0";
// JSONRPCClient needs to know how to send a JSON-RPC request.
// Tell it by passing a function to its constructor. The function must take a JSON-RPC request and send it.
const client = new JSONRPCClient(
(jsonRPCRequest) =>
fetch("http://localhost/json-rpc", {
method: "POST",
headers: {
"content-type": "application/json"
},
body: JSON.stringify(jsonRPCRequest)
}).then(response => {
if (response.status === 200) {
// Use client.receive when you received a JSON-RPC response.
return response.json().then(jsonRPCResponse => client.receive(jsonRPCResponse));
} else if (jsonRPCRequest.id !== undefined) {
client.receive(createJSONRPCErrorResponse(jsonRPCRequest.id, 0, response.statusText));
}
})
);
// Use client.request to make a JSON-RPC request call.
// The function returns a promise of the result.
client.request("echo", { text: "Hello, World!" }).then(result => console.log(result));
// Use client.notify to make a JSON-RPC notification call.
// By definition, JSON-RPC notification does not respond.
client.notify("log", { message: "Hello, World!" });
With authentication
Just like JSONRPCServer
, you can inject custom params to JSONRPCClient
too:
const client = new JSONRPCClient(
// If it is a higher-order function, it passes the custom params to the returned function.
(jsonRPCRequest) => ({ token }) =>
fetch("http://localhost/json-rpc", {
method: "POST",
headers: {
"content-type": "application/json",
authorization: `Bearer ${token}` // Use the passed token
},
body: JSON.stringify(jsonRPCRequest)
}).then(response => {
// ...
})
);
// Pass the custom params as the third argument.
client.request("echo", { text: "Hello, World!" }, { token: "foo's token" });
client.notify("log", { message: "Hello, World!" }, { token: "foo's token" });
Build
npm run build
Test
npm test