expose async functions as an api


Keywords
rpc, json, jsonrpc, json-rpc, api, web-api, node-api, api-client, api-library, json-api, remote-procedure-call
License
MIT
Install
npm install renraku@0.0.3

Documentation

連絡
れんらく
R·E·N·R·A·K·U

npm install renraku

🔆 make smart typescript apis
🛎️ simply expose async functions
🛡 you set auth policies for groups of functions
🎭 easy mocks for testing and development
🧠 designed for good typescript types
🌐 make http json-rpc apis
🔁 make bidirectional websocket json-rpc apis


⛩️ RENRAKU teaches by example

  1. let's make an example api

    import * as renraku from "renraku"
    
    export const exampleApi = renraku.api({
    
      // we organize functions into services.
      greeter: renraku.service()
    
        // each service has its own auth policy.
        // a policy processes a "meta" object into an "auth" object.
        // this is where you might process access tokens, or verify permissions.
        // here's our contrived example policy.
        .policy(async(meta: {token: string}) => {
          if (meta.token) return {doctorate: meta.token === "doctor"}
          else throw new Error("invalid token")
        })
    
        // here's where our functions get access to our "auth" object.
        .expose(auth => ({
    
          // here's our silly example function.
          async greet(name: string) {
            return auth.doctorate   // if the user's doctorate is valid,
              ? `hello dr. ${name}` // we greet them formally,
              : `hi ${name}`        // otherwise, we greet them differently.
          },
        })),
    })
  2. now let's run our api on a node server

    import * as renraku from "renraku"
    import {nodeServer} from "renraku/x/http/node-server.js"
    import {exampleApi} from "./example-api.js"
    
    const server = nodeServer({
      api: exampleApi,
      exposeErrors: false,
      maxPayloadSize: renraku.megabytes(10),
    })
    
    server.listen(8000)
  3. now let's call that function from a browser

    import * as renraku from "renraku"
    import type {exampleApi} from "./example-api.js"
    
    // let's start as a doctor
    let meta = {token: "doctor"}
    
    // we create a browser client
    const {greeter} = renraku.browserClient({
      url: "http://localhost:8000/",
      metaMap: {
        // on the service, we specify which meta to use for api calls
        calculator: async() => meta,
      },
    })
    
    // hey look, we're a doctor!
    const result1 = await greeter.greet("chase")
      //> "hello, dr. chase"
    
    // okay let's stop being a doctor
    meta = {token: "not a doctor"}
    const result2 = await greeter.greet("chase")
      //> "hi chase"
    
    // now let's just fail to provide a valid meta
    meta = {token: undefined}
    const result3 = await greeter.greet("chase")
      //> ERROR! "invalid token"

⛩️ RENRAKU mocks help you test your app

  1. let's test our example-api, locally, in our test suite

    import * as renraku from "renraku"
    import {exampleApi} from "./example-api.js"
    
    // okay, let's start with a valid doctor token
    let meta = {token: "doctor"}
    
    // create a mock remote of our api
    const {greeter} = renraku.mock()
      .forApi(exampleApi)
      .withMetaMap({
        greeter: async() => meta,
      })
    
    // now we can call and test our api's functionality,
    // without running any servers, or clients, or any of that.
    
    const result1 = await greeter.greet("chase")
      //> "hello, dr. chase"
    
    meta = {token: "not a doctor"}
    const result2 = await greeter.greet("chase")
      //> "hi chase"
    
    // not only are we testing our api's business logic,
    // but we are also testing the auth policies too!
  2. when making our mocks, we may choose to skip the auth policy logic

    const {greeter} = renraku.mock()
      .forApi(exampleApi)
    
      // 👇 an auth map overrides auth policies
      .withAuthMap({
    
        //          we're forcing this auth result
        //                    👇
        greeter: async() => ({doctorate: true}),
      })

⛩️ RENRAKU error handling

    ~ readme docs coming soon lol ~


⛩️ RENRAKU also lets you build two-way websocket systems

    ~ readme docs coming soon lol ~



      — RENRAKU means "contact" —