Furver is a minimal RPC solution that uses JSON and Node.js. Turn any JavaScript module into a simple to use client API that is easy to learn while also expressive enough for advanced use-cases.
Table of Contents
- Low code.
- Makes it easy to quickly iterate.
- Supports bulk requests with an intuitive client js API.
- Parallel operations out of the box.
- Covers both simple and complicated use-cases.
Covers the basic use case of defining a module, starting a server and performing requests with and without the client.
npm install furver -g
// ./example/getting-started.mjs
const items = []
export default {
push (x) {
return items.push(x)
},
items () {
return items
},
ping () {
return 'pong'
}
}
Port 5000 for the following examples.
furver server ./example/getting-started.mjs --port 5000
Now for the http clients.
curl http://localhost:5000 -d '["ping"]'
"pong"
Let's add some numbers to our items
array.
curl http://localhost:5000 -d '["array", ["push", 1], ["push", 2], ["push", 3], ["items"]]'
[1,2,3,[1,2,3]]
Also support requests with GET
method:
curl -G "http://localhost:$PORT" --data-urlencode body='["inc", 42]'
43
We use the
-G
and--data-urlencode
to perform a GET request with properly encoded JSON in the body query param.
Now let's use the furver client module and api.push
some letters.
import client from './client.mjs'
const api = await client({
endpoint: 'http://localhost:5000'
})
console.log(await Promise.all([
api.push('a'),
api.call(['push', 'b']),
api.call([['ref', 'push'], 'c']),
api.call([api.push, 'd'])
]))
console.log(await api.items())
[ 4, 5, 6, 7 ]
[
1, 2, 3, 'a',
'b', 'c', 'd'
]
These are all equivalent ways of calling the push function in the server module. Read more about the client and lisp if you want to learn more.
You can start a server by pointing to a module. This can be a npm package or another file on the filesystem.
npm install ramda # A utility library.
npx furver server --port 3000 ramda ./example/api.mjs
Defining multiple modules will result in the modules being merged into a single API. The function of the most right module will take precedence when the modules have conflicting function names.
You can now perform requests using a furver client.
Read more about the Furver server.
Now that we have a server running we can use the client to perform requests using either the client functions or a simple JSON Lisp.
Here an working example of the JavaScript client.
(async function() {
const { default: FurverClient } = await import('./client.mjs')
// Fetches the schema and installs the schema methods on the api.
const api = await FurverClient({endpoint: `http://localhost:${process.env.PORT}`})
// These function calls result in a single request that is run in parallel on
// the server.
console.log(await Promise.all([
api.identity('hello world'),
api.timestamp(),
api.version()
]))
// We can write the same query using the JSON Lisp
console.log(await api.call(['array', ['identity', 'hello world'], ['timestamp'], ['version']]))
// Those are many quotes, we can reduce it by using the function reference.
const { identity, timestamp, version, array } = api
console.log(await api.call([array, [identity, 'hello world'], [timestamp], [version]]))
})()
[ 'hello world', 1694650272974, '1.2.1' ]
[ 'hello world', 1694650272979, '1.2.1' ]
[ 'hello world', 1694650272982, '1.2.1' ]
All three ways are equivalent and valid ways of writing a furver Lisp program that is run server-side.
This client is compatible with the browser and Node.js.
You can also start talking with a Furver server using the cli.
furver repl --url http://localhost:3000
This will start a prompt that takes valid JavaScript or a Lisp expression.
> identity('hello')
"hello"
> ['identity', 'world']
"world"
> [identity, 'goodbye']
"goodbye"
By default the server hosts a browser friendly bundled version of the client at
/client.min.js
. This script registers the furver
global variable.
You can try this client in the playground by starting a furver server and
opening http://localhost:3000/playground
in your browser.
Furver's Lisp-like language allows developers to perform complex aggregations and operations in a single request. It builds ontop of JSON by using arrays for its s-expressions.
Read more about the furver lisp.
The goal of Furver's cli is to provide you with all the tools to use, test and debug Furver servers.
furver --help
furver <command>
Commands:
furver server <modules..> start server
furver repl [modules..] start a local server or client repl
furver client start client repl. Use repl --url instead
[deprecated]
furver schema [modules..] print schema of api
Options:
--help Show help [boolean]
--version Show version number [boolean]
--url [string]
--modules Name or path to modules [array]
-v, --verbose [boolean]
-p, --port [number] [default: "8999"]
Read more about the Furver CLI.
See the CHANGELOG.md for a list of changes over time.
Want to contribute? The CONTRIBUTING.md might help you get started quicker.
See the LICENSE.txt file for details.