Qubit - Rust/TypeScript RPC
Generate type-safe TypeScript clients for your Rust APIs, with Serde compatibility, subscriptions, and more!
Features:
-
Context based middleware
-
Subscriptions
-
Nested routers
-
Serde compatibility for serialising and deserialising parameters and return values
-
Standardised JSONRPC 2.0 implementation, including
wsandhttptransport layers
Example
Check out the example directory for a full example.
Rust Server
// Handlers are defined as functions, where the function name will be the name of the handler
async
// Handlers have access to the app state
async
// Handlers can accept parameters
async
// Handlers can return a stream, in order to act as a subscription
async
async
TypeScript
import { ws } from "@qubit-rs/client";
// This type is automatically generated based on the Rust API
import type { Server } from "./bindings.ts";
// Start a new client, passing the type as a generic parameter
const client = ws<Server>("ws://localhost:9944/rpc");
// Handlers can be accessed from the client just by calling the method!
const message = await client.hello_world();
console.log(message); // "Hello, world!"
for (let i = 0; i < 5; i++) {
const count = await client.count();
console.log(`The count is: ${count}`);
}
// Parameters are typed, and are passed as if it were a regular function
await client.count_by(10);
// Subscriptions are just like regular handlers, except they also accept life-cycle handlers for
// data, errors, and subcription end
await client.countdown(1, 4).subscribe({
on_data: (data) => {
console.log(`Countdown: ${data}`);
},
on_end: () => {
console.log("Countdown done!");
}
});
Acknowledgements
-
rspc: Similar concept, however uses a bespoke solution for generating TypeScript types from Rust structs, which isn't completely compatible with all of Serde's features for serialising and deserialising structs. -
trpc: Needs no introduction, however it being restricted to TypeScript backends makes it relatively useless for Rust developers.