gentle_rpc

JSON-RPC 2.0 TypeScript library for deno and the browser.

This library is accessible through the https://deno.land/x/ service or through https://nest.land/package/gentle_rpc.

Features

  • Complies with the JSON-RPC 2.0 specification
  • Sends data with the fetch API
  • Uses JavaScript/TypeScript native proxies for a simple API on the client side

Example

Always use versioned imports for your dependencies. For example https://deno.land/x/gentle_rpc@v1.6/rpcServer.ts.

Server/deno side

import { serve } from "https://deno.land/std@0.74.0/http/server.ts";
import { respond } from "https://deno.land/x/gentle_rpc/respond.ts";

console.log("listening on 0.0.0.0:8000");
const s = serve("0.0.0.0:8000");

const rpcMethods = {
  sayHello: ([w]: [string]) => `Hello ${w}`,
  animalsMakeNoise: ([noise]: [string]) => noise.toUpperCase(),
};

for await (const req of s) {
  await respond(req, rpcMethods);
}

Client/remote side

import { createRemote } from "https://deno.land/x/gentle_rpc/request.ts";

const remote = createRemote("http://0.0.0.0:8000");
const greeting = await remote.sayHello(["World"]);

console.log(greeting); // Hello World

API

respond(request, methods, { additionalArgument? })

The additional argument is optional.

for await (const req of s) {
  await respond(req, rpcMethods, { additionalArgument: db });
}

createRemote(resource, options) => Proxy

  • url: string | URL | Request the URL to fetch data from.
  • options: Options this object sets the fetch API options (RequestInit). Additionally, it contains the two optional properties:
    • notification causes the server to make an empty response.
    • id defines a custom id.

remote.method(value[] | {key: value}) => Promise<JsonValue | undefined>

Each method call of the remote object will look for the identically named method on the server side, where the methods are defined.

const remote = createRemote("http://0.0.0.0:8000");
await remote.sayHello(["World"]); // Hello World

Batch Requests

remote.batch(["method", ["arg1"], ["arg1", "arg2"], ...])

await remote.batch([
  "animalsMakeNoise",
  ["miaaow"],
  ["wuuuufu"],
  ["iaaaiaia"],
  ["fiiiiire"],
]);
// [ "MIAAOW", "WUUUUFU", "IAAAIAIA", "FIIIIIRE" ]

remote.batch({key1: ["method1", ["arg1", "arg2"]], key2: ["method2", ["arg1"]], ...})

This way of making batch requests uses the object keys (cat, dog, donkey, dragon) as RPC request object ids under the hood. The returned RPC result values will be assigned to these keys. Let's take a look at the following example:

const noise2 = await remote.batch({
  cat: ["sayHello", ["miaaow"]],
  dog: ["animalsMakeNoise", ["wuuuufu"]],
  donkey: ["sayHello"],
  dragon: ["animalsMakeNoise", ["fiiiiire"]],
});
// { cat: "Hello miaaow", dog: "WUUUUFU", donkey: "Hello ", dragon: "FIIIIIRE" }

Examples and Tests

Checkout the examples and tests folders for more detailed examples.

Contribution

Every kind of contribution to this project is highly appreciated.
Please run deno fmt on the changed files before making a pull request.