Package Exports
- renraku
- renraku/dist/client/create-api-client.js
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 (renraku) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
連絡
れんらく
R·E·N·R·A·K·U
— node api library —
featuring seamless calling
RENRAKU creates seamless node api's
traditionally, to call an api, you'd do something like this:
// old and not cool
const userDetails = await api.apiCall("user.getDetails", [userId])
introducing RENRAKU!
// the future
const userDetails = await user.getDetails(userId)
RENRAKU features:
- natural syntax with no more string literals to maintain
- interchangable client object and server implementation (great for testing)
- typings provide intellisense hints
- typescript devs see errors in realtime (errors like a client/server api signature mismatch)
RENRAKU terminology:
api
contains topicstopic
contains functionsshape
is json describing topic signature
RENRAKU leads by example
server.js
— on your node server, expose some functionality
import {createApiServer} from "renraku"
const server = createApiServer({
exposures: [
{
allowed: /^http\:\/\/localhost\:8\d{3}$/i,
forbidden: /\:8989$/i,
exposed: {
reactor: {
async generatePower(a, b) { return a + b },
async radioactiveMeltdown(): Promise<void> {
throw new Error("meltdown error")
}
}
}
}
]
})
server.start(8001)
- topic objects must only have async functions
- you can pass multiple exposures to expose different topics to different origins
client.js
— call your functions from node or a browser
import {createApiClient} from "renraku"
async function main() {
// create the renraku client
const {reactor} = await createApiClient({
url: "http://localhost:8001",
shape: {
reactor: {
generatePower: true,
radioactiveMeltdown: true
}
}
})
// ergonomic usage
const result1 = await reactor.generatePower(1, 2)
console.log(result1)
//> 3
const result2 = await reactor.radioactiveMeltdown()
//> Error: meltdown error
}
- you have to describe the shape of the api to the client.
this allows RENRAKU to generate callable topic functions.
if you use typescript, it will enforce that the shape is correctly maintained
RENRAKU is good for typescript devs
to use RENRAKU, the javascript examples above are all you need
additionally however, typescript devs can benefit by receiving compile-time errors, for example whenever a clientside shape object doesn't match a serverside implementation
to achieve this, carefully follow the examples below, and pay special attention to the usage of AbstractApiTopic
on the serverside
common.ts
import {Api, Topic} from "renraku"
// topic interface, shared between server and client
export interface ReactorTopic extends Topic {
generatePower(a: number): Promise<number>
radioactiveMeltdown(a: number, b: number): Promise<number>
}
// api interface, shared between server and client
export interface NuclearApi extends Api {
reactor: ReactorTopic
}
server.ts
import {createApiServer, AbstractTopic} from "renraku"
import {NuclearApi, ReactorTopic} from "./common"
class Reactor extends AbstractTopic implements ReactorTopic {
async generatePower(a: number, b: number) { return a + b },
async radioactiveMeltdown() { throw new Error("meltdown error") }
}
const server = createApiServer<NuclearApi>({
exposures: [
{
allowed: /^http\:\/\/localhost\:8\d{3}$/i,
forbidden: /\:8989$/i,
exposed: {
reactor: new Reactor()
}
}
]
)
client.ts
import {createApiClient} from "renraku"
import {NuclearApi, nuclearApiShape} from "./common"
const nuclearApiShape: ApiShape<NuclearApi> = {
reactor: {
generatePower: true,
radioactiveMeltdown: true
}
}
async function main() {
const {reactor} = await createApiClient<NuclearApi>({
url: "http://localhost:8001",
shape: nuclearApiShape
})
const result = await reactor.generatePower(1, 2)
console.log(result)
//> 3
}
— RENRAKU means 'contact' —