npm package: @r1000ru/jsonrpc-server
Description: HTTP Server for JSON-RPC specification
Author: Roman Sorokin
Latest version: 0.1.0

# JsonRPC Server

Легковесный http-сервер для работы создания API по [спецификации JsonRPC](http://www.jsonrpc.org/specification). Сервер не использует никаких внешних зависимостей.

### Кратенько о протоколе

В запросах к серверу всегда отправляется POST сообщение, в теле которого содержится json-запрос типа:

```
{
    "jsonrpc": "2.0",       // Обязательный признак спецификации
    "method": "subtract",   // Обязательное название метода, который должен быть выполнен на сервере
    "params": [42, 23],     // Обязательные параметры для метода - объект или массив
    "id": 1                 // Необязательный идентификатор запроса. Учтите, если его нет - ответ будет пустой
}
```

и в ответ сервер отправляет json-ответ типа:

```
{
    "jsonrpc": "2.0",       // Обязательный признак спецификации
    "result": 19,           // Обязательный результат - может быть любого типа
    "id": 1                 // Необязательный идентификатор ответа. Всегда равен идентификатору запроса
}
```

или  ошибку

```
{
    "jsonrpc": "2.0",       // Обязательный признак спецификации
    "error": {              // Обязательный объект ошибки
        "code": -32601,                 // Обязательный код ошибки
        "message": "Method not found"   // Обязательное сообщение об ошибке
        "data": "nothing"               // Не обязательные дополнительные данные об ошибке любого типа
    },
    "id": "1"               // Необязательный идентификатор ответа. Всегда равен идентификатору запроса
}
```

### Начало работы

1. Установите пакет сервера: `npm install jsonrpc-server`
1. Напишите код:
```
// Подключаем модуль
const JsonRPCServer = require('jsonrpc-server');

// Создаем экземпляр сервера
var server = new JsonRPCServer();

// Обработчик на метод Ping
server.on('Ping', (params, conn) => {
    conn.result('Pong');
});

// Обработчик на метод Hello, свойство title - обязательно
server.on('Hello', {
    title: true
}, (params, conn)=>{
    conn.result('Hello, ' + params.title + '!');
});

// Обработчик на метод Summary - сумма элементов массива без ограничения по длине
server.on('Summary', 0, (params, conn) => {
    let sum = 0;
    for (let i in params) {
        sum += params[i];
    }
    conn.result(sum);
});

// Возврат ошибки
server.on('ItIsNotWork', (params, conn)=>{
    conn.error({
        code: 1,
        message: 'User error'
    });
});

// Если в результате выполнения может быть как ошибка, так и результат и необходимо разобрать
server.on('WorkOrNotWork', (params, conn)=>{
    // Выполняем какую-то логику
    myFunc((err, result) => {
        conn.send(err, result);
    });
});

// Запустим сервер
server.listen();
```

### API

 - **JsonRPCServer.listen ([port, [interface]])** - запуск сервера.
   - *port* - необязательный аргумент номера порта, который будет слушать сервер. Если не указан, устанавливается 8080
   - *interface* - необязательный аргумент сетевого интерфейса (ip-адрес), который будет слушать сервер. Может устанавливаться только после порта. Если не указан, устанваливается *localhost*

 - **JsonRPCServer.setError(type, error)** - переопределение стандартных ошибок.
   - *type* - тип ошибки: PARSE_ERROR, INVALID_REQUEST, METHOD_IS_NOT_FOUND, INVALID_PARAMS, INTERNAL_ERROR, SERVER_ERROR
   - *error* - стандартный объект ошибки: `{code: N, message: 'your message'}`

 - **JsonRPCServer.on(method, [rules], onRequestCallback)** - установка реакции на запрос к какому-либо методу.
   - *method* - обязательный аргумент названия метода
   - *rules* - необязательный аргумент правил проверки параметров. Если не указан - параметры останутся в неизменном виде. Если это *0* - в параметрах ожидается массив любой длины. Если это *число* - в параметрах ожидается массив, длинной в это *число*. Если это объект, то переданы будут только те свойства параметров, которые указаны в *rules*. При этом, если в правилах свойство равно *true* - оно обязательно, *false* - не обязательно, *null* - не обязательно, и если есть и равно *null*, *0* или *пустой строке* - свойству параметра будет присвоено *null*

   - *onRequestCallback(checkedParams, **jsonRPC**)* - функция, которая будет вызвана при получении запроса на метод и после проверки параметров. В функция аргументами передаются параметры и объект **JsonRPC** для возврата ошибки или результата
 

 - **JsonRPC.send(error, result)** - метод отправляет ответ на запрос. Если *error* присутствует - будет передан он, если нет - будет передан результат
 - **JsonRPC.error(result)** - метод отправляет результат на запрос.
 - **JsonRPC.error(error)** - метод отправляет ошибку на запрос. Следует заметить, что *error* - должен быть объект ошибки по спецификации (т.е. иметь поля *code* и *message*)