An open API service indexing awesome lists of open source software.

https://github.com/sangaman/http-jsonrpc-server

A simple and lightweight library for creating a JSON-RPC 2.0 compliant HTTP server
https://github.com/sangaman/http-jsonrpc-server

http-server json-rpc json-rpc-server json-rpc2

Last synced: 6 months ago
JSON representation

A simple and lightweight library for creating a JSON-RPC 2.0 compliant HTTP server

Awesome Lists containing this project

README

          

# http-jsonrpc-server

![GitHub Actions Build](https://github.com/sangaman/http-jsonrpc-server/actions/workflows/master.yaml/badge.svg)
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=sangaman_http-jsonrpc-server&metric=coverage)](https://sonarcloud.io/summary/new_code?id=sangaman_http-jsonrpc-server)
[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=sangaman_http-jsonrpc-server&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=sangaman_http-jsonrpc-server)
[![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=sangaman_http-jsonrpc-server&metric=reliability_rating)](https://sonarcloud.io/summary/new_code?id=sangaman_http-jsonrpc-server)
[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=sangaman_http-jsonrpc-server&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=sangaman_http-jsonrpc-server)[![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=sangaman_http-jsonrpc-server&metric=ncloc)](https://sonarcloud.io/summary/new_code?id=sangaman_http-jsonrpc-server)
[![Socket Badge](https://socket.dev/api/badge/npm/package/http-jsonrpc-server)](https://socket.dev/npm/package/http-jsonrpc-server)
[![License: MIT](https://img.shields.io/badge/License-MIT%202.0-brightgreen.svg)](https://opensource.org/licenses/MIT)

- [http-jsonrpc-server](#http-jsonrpc-server)
- [Install](#install)
- [Usage](#usage)
- [Specifying a Path](#specifying-a-path)
- [Optional Callbacks](#optional-callbacks)
- [Adding/Updating Methods](#addingupdating-methods)
- [Closing the Server](#closing-the-server)
- [Basic Authentication](#basic-authentication)
- [Native HTTP Server](#native-http-server)
- [Exposed Constants](#exposed-constants)
- [API Documentation](#api-documentation)
- [RpcServer](#rpcserver)
- [new RpcServer(options)](#new-rpcserveroptions)
- [rpcServer.setMethod(name, method)](#rpcserversetmethodname-method)
- [rpcServer.listen(port, host) ⇒ Promise.<number>](#rpcserverlistenport-host--codepromiseltnumbergtcode)
- [rpcServer.close() ⇒ Promise.<void>](#rpcserverclose--codepromiseltvoidgtcode)
- [Sample Requests](#sample-requests)
- [Sum](#sum)
- [Sum (Batched)](#sum-batched)
- [Wait](#wait)

A simple and lightweight library for creating a JSON-RPC 2.0 compliant HTTP server.

This package complies with the [JSON-RPC 2.0](http://www.jsonrpc.org/specification) and [JSON-RPC 2.0 Transport: HTTP](https://www.simple-is-better.org/json-rpc/transport_http.html) specifications.

## Install

To install http-jsonrpc-server in the current directory, run:

```bash
npm install http-jsonrpc-server --save
```

## Usage

Below is code to create a server with two exposed methods and begin listening on a given port.

```javascript
const RpcServer = require('http-jsonrpc-server');

function sum(arr) {
let total = 0;
for (let n = 0; n < arr.length; n += 1) {
total += arr[n];
}
return total;
}

async function wait(params) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(true);
}, params.ms);
});
}

const rpcServer = new RpcServer({
methods: {
sum,
wait,
}
});
rpcServer.setMethod('sum', sum);
rpcServer.setMethod('wait', wait);
rpcServer.listen(9090, '127.0.0.1').then(() => {
console.log('server is listening at http://127.0.0.1:9090/');
}
```

### Specifying a Path

```javascript
const rpcServer = new RpcServer({
path: '/api'
});
rpcServer.listen(9090, '127.0.0.1').then(() => {
console.log('server is listening at http://127.0.0.1:9090/api');
}
```

### Optional Callbacks

`onServerError` will be called if the server emits an [error](https://nodejs.org/api/net.html#net_event_error). `onRequest`, and `onRequestError`, and `onResult` will be called each time a method is called, throws an error, or returns a result respectively.

```javascript
const rpcServer = new RpcServer({
onRequest: (request) => {
console.log(JSON.stringify(request));
// sample output: {"jsonrpc":"2.0","id":1,"method":"sum","params":[1,2,3]}
},
onRequestError: (err, id) => {
console.error('request ' + id + ' threw an error: ' + err);
},
onResult: (result, id) => {
console.log(result); // sample output: 6
},
onServerError: (err) => {
console.error('the server threw an error: ' + err)
},
});
```

### Adding/Updating Methods

You can register new methods or update existing ones after the server has been created.

```javascript
rpcServer.setMethod('sum', sum);
```

### Closing the Server

```javascript
rpcServer.close().then(() => {
console.log('server stopped listening');
}
```

### Basic Authentication

You can optionally enable [Basic Authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication) by specifying credentials when creating the server. Any requests will then require an `Authorization` header with `[username]:[password]` encoded in Base64. Note that TLS is not currently supported, therefore all traffic is unencrypted and these credentials can be stolen by anyone relaying or listening to requests. This authentication alone should not be considered secure over public networks.

```javascript
const rpcServer = new RpcServer({
username: 'johndoe',
password: 'wasspord', // ignored unless username is specified
realm: 'rpc' // realm defaults to "Restricted" if not specified
});
```

### Native HTTP Server

You can access the underlying [http.Server](https://nodejs.org/api/http.html#http_class_http_server) object with `rpcServer.server`.

```javascript
if (rpcServer.server.listening) {
console.log('server is listening');
}
```

### Exposed Constants

```javascript
console.log(rpcServer.PARSE_ERROR); // -32700
console.log(rpcServer.INVALID_REQUEST); // -32600
console.log(rpcServer.METHOD_NOT_FOUND); // -32601
console.log(rpcServer.INVALID_PARAMS); // -32602
console.log(rpcServer.SERVER_ERROR); // -32000
console.log(rpcServer.SERVER_ERROR_MAX); // -32099
```

## API Documentation

## RpcServer
Class representing a HTTP JSON-RPC server

**Kind**: global class

* [RpcServer](#RpcServer)
* [new RpcServer(options)](#new_RpcServer_new)
* [.setMethod(name, method)](#RpcServer+setMethod)
* [.listen(port, host)](#RpcServer+listen) ⇒ Promise.<number>
* [.close()](#RpcServer+close) ⇒ Promise.<void>

### new RpcServer(options)

| Param | Type | Description |
| --- | --- | --- |
| options | Object | Optional parameters for the server |
| options.methods | Object | A map of method names to functions. Method functions are passed one parameter which will either be an Object or a string array |
| options.context | | Context to be used as `this` for method functions. |
| options.path | string | The path for the server |
| options.onRequest | function | Callback for when requests are received, it is passed an Object representing the request |
| options.onRequestError | function | Callback for when requested methods throw errors, it is passed an error and request id |
| options.onResult | function | Callback for when requests are successfully returned a result. It is passed the response object and request id |
| options.onServerError | function | Callback for server errors, it is passed an [Error](https://nodejs.org/api/errors.html#errors_class_error) |
| options.username | string | Username for authentication. If provided, Basic Authentication will be enabled and required for all requests. |
| options.password | string | Password for authentication, ignored unless a username is also specified. |
| options.realm | string | Realm for authentication, ignored unless a username is also specified, defaults to `Restricted` if not specified. |

### rpcServer.setMethod(name, method)
Sets a method.

**Kind**: instance method of [RpcServer](#RpcServer)

| Param | Type | Description |
| --- | --- | --- |
| name | string | The name of the method |
| method | function | The function to be called for this method. Method functions are passed one parameter which will either be an Object or a string array. |

### rpcServer.listen(port, host) ⇒ Promise.<number>
Begins listening on a given port and host.

**Kind**: instance method of [RpcServer](#RpcServer)
**Returns**: Promise.<number> - A promise that resolves to the assigned port once the server is
listening. On error the promise will be rejected with an [Error](https://nodejs.org/api/errors.html#errors_class_error).

| Param | Type | Description |
| --- | --- | --- |
| port | number | The port number to listen on - an arbitrary available port is used if no port is specified |
| host | string | The host name or ip address to listen on - the unspecified IP address (`0.0.0.0` or `(::)`) is used if no host is specified |

### rpcServer.close() ⇒ Promise.<void>
Stops listening on all ports.

**Kind**: instance method of [RpcServer](#RpcServer)
**Returns**: Promise.<void> - A promise that resolves once the server stops listening. On error the
promise will be rejected with an [Error](https://nodejs.org/api/errors.html#errors_class_error).

## Sample Requests

Here are some sample requests made against the server created in the first [usage](#usage) example.

### Sum

```http
POST / HTTP/1.1
Host: 127.0.0.1:9090
Content-Type: application/json
Accept: application/json
Content-Length: 56

{"jsonrpc":"2.0","id":1,"method":"sum","params":[1,2,3]}
```

```http
connection: close
content-type: application/json
content-length: 35

{"jsonrpc":"2.0","id":1,"result":6}
```

### Sum (Batched)

```http
POST / HTTP/1.1
Host: 127.0.0.1:9090
Content-Type: application/json
Accept: application/json
Content-Length: 115

[{"jsonrpc":"2.0","id":1,"method":"sum","params":[1,2,3]},{"jsonrpc":"2.0","id":2,"method":"sum","params":[4,5,6]}]
```

```http
connection: close
content-type: application/json
content-length: 74

[{"jsonrpc":"2.0","id":1,"result":6},{"jsonrpc":"2.0","id":2,"result":15}]
```

### Wait

```http
POST / HTTP/1.1
Host: 127.0.0.1:9090
Content-Type: application/json
Accept: application/json
Content-Length: 59

{"jsonrpc":"2.0","id":1,"method":"wait","params":{"ms":50}}
```

```http
connection: close
content-type: application/json
content-length: 38

{"jsonrpc":"2.0","id":1,"result":true}
```