RPC Docs.

Prim+RPC is prerelease software. It may be unstable and functionality may change prior to full release.

Introduction

TLDR: Prim+RPC is an easy-to-understand, type-safe, transport-agnostic RPC/IPC framework for JavaScript, supporting callbacks, batching, file uploads, custom serialization, and more.

Use Prim+RPC to communicate between different JavaScript environments where functions can't be called directly, such as client and server. Prim+RPC allows you to focus less on message transport and more on the message being sent.

Ready to get get started?

Table of Contents

What is it?

Prim+RPC (pronounced "Prim RPC") is a bridge between JavaScript environments, without the extra boilerplate code. The primary use of this library is making plain function calls to a server from some client (RPC), as if that code had been written on the client itself. The goal is to write plain JavaScript, or TypeScript if you prefer, and immediately invoke typed code without verbose wrappers around the communication channel.

server.ts

// import the Prim+RPC server
import { createPrimServer } from "@doseofted/prim-rpc"
// create any ordinary function
export function sayHello(x, y) {
return `${x}, meet ${y}.`
}
// signal that this function is intended to be called as RPC
sayHello.rpc = true
// pass your function to Prim+RPC server
const prim = createPrimServer({
module: { sayHello },
// ... setup transport options (described in documentation)
})
// now make RPC from the client

client.ts

// import Prim+RPC client
import { createPrimClient } from "@doseofted/prim-rpc"
// import types from server
import type * as module from "./server.ts"
// configure client with types and endpoint used on the server
const { sayHello } = createPrimClient<typeof module>({
endpoint: "http://localhost:1234/prim",
// ... setup transport options (described in documentation)
})
// call function as if it exists on the client (which it doesn't)
const greeting = await sayHello("Backend", "Frontend")
// greeting === "Backend, meet Frontend."

Importantly, Prim+RPC does not dictate or have a preference regarding how you send or receive RPC. This means that Prim+RPC can be used to bridge any two kinds of JavaScript environments where communication is otherwise difficult. This could mean communication between two physically separated servers, between a server and client, or between two separate processes/threads. Prim+RPC can connect all of these environments, with type definitions attached, and without the need for a separate schema/definition language.

Prim+RPC is written in TypeScript and allows you to take advantage of type definitions in your code from one environment to another without manually copying or recreating definitions, whether those are written in TypeScript or JavaScript with JSDoc comments. There's also no client generation script or other transpilation step needed to access type definitions since any types you've already written inside of your code are utilized by Prim+RPC.

In addition to the library itself, Prim+RPC also includes a low-level documentation generator that you can use to generate your own custom documentation website for your RPC (both JavaScript and TypeScript). This output could even be used to generate requests for non-JavaScript environments. On the topic of other environments, the RPC created with Prim+RPC is purposefully very simple and easy to structure, in the event that you need to use code outside of JavaScript. In the future, this documentation may also be used to generate a JSON schema for your RPC so that other languages can have typed requests by making their requests with JSON.

Prim+RPC is created with the goal of allowing you to write the code that you actually want to write with the tools that you already enjoy using. While other tools require separate type/schema definitions, Prim+RPC takes advantage of existing types in your JavaScript/TypeScript. While other tools require generation of a client-side code to communicate with a server, Prim+RPC utilizes JavaScript Proxies to automatically generate the correct RPC code based on your function calls. While other tools generally assume usage over HTTP, Prim+RPC utilizes separate plugins to communicate over any channel that you'd like (with default plugins, of course).

While file uploads, serialization of data, batching of requests, and server-sent data are considered separate features to be implemented in other tools, Prim+RPC supports these out of the box either directly or by utilizing a third party tool, with minimal setup on the developer's side.

In short, Prim+RPC allows you to focus less on message transport and more on the message being sent.

How Does It Work?

There are two parts of Prim+RPC for communicating between two different environments, referred to as server and client. The server/client could be two distinct processes communicating with each other (IPC) or it could be a web server communicating with a web browser (RPC, a form of IPC).

The server is responsible for making your code available to the client. You can write any plain JavaScript function that you'd like, pass it to Prim+RPC, and it becomes available for the client to use once flagged as publicly available (nothing is shared by default). The server reads given RPC, a simple JSON object typically transported over HTTP or WebSocket, and translates this into the proper function call on the server.

The client is responsible for structuring requests into RPC that the server can understand. When you make a function call using the client, that function call is translated into RPC using a recursive JavaScript Proxy. The Proxy object is JavaScript's answer to meta-programming and allows tools like Prim+RPC to inspect usage of properties and methods on an object. This means that Prim+RPC doesn't need to generate a client to communicate with the server. Instead, it uses the language itself.

There are many other more intricate details concerning how Prim+RPC works: batching requests, handling files, interaction with plugins, just to name a few. These are topics that may be covered in-depth as this documentation progresses.

Next Steps

This introduction has only discussed the basic RPC features available with Prim+RPC. There are many additional features like callback support and file upload handling, options that you can configure, plugins that you can utilize (or create your own), serialization handlers for RPC that you can customize, documentation that you can generate, and more.

You can learn how to set up your own project or see the available examples to get started! Once your project is set up you can then learn how to use Prim+RPC!

Framework Goals

I personally work with many different frameworks and created Prim+RPC to make working with various frontends and backends easier by making an RPC framework that is highly modular and can work with any frontend or backend. It is also a necessary stepping block for me to build Prim+CMS, for which I'll be announcing more details in the future. Moving forward, I'm looking to move Prim+RPC from prerelease to general release, add new features, and take steps to make the RPC structure stable so that it's easy for other tools and services to implement.

I chose to make this project open source for several reasons: to encourage adoption, gather community feedback, for the security that open source can provide, but primarily because many of the tools that I use today are also open source. The availability of these tools have allowed me to learn and experiment and are a big part of why I am a developer today, and that ecosystem is something for which I'd like to contribute back. I hope that you find this library useful and that it helps other developers like yourself whether you are experienced or just starting out.

Support

If you do find this tool useful, consider sharing it with others, giving it a star on Github, contributing back to the project (whether to the core project or a plugin for it), sponsoring the project, or utilizing the tool as part of your own API.

Prim+RPC: a project by Ted Klingenberg

Dose of Ted

Anonymous analytics collected with Ackee