Пакет для создания API серверов на NodeJS. Сервер может использовать два вида транспортных протоколов: WebSocket и HTTP, поддерживает механизм подписок и простю авторизацию/аутентификацию пользователей на основе сессий. Для взаимодействия с сервером используется протокол JSON-RPC 2.0. Протоколы: HTTP/S, WebSocket.
- Требования
- Установка
- Использование
- Классы
- Объекты сервисы
- Функции
- Интерфейсы
- Список встроенных ошибок и кодов
- Готовые модули
- Версия Node.js >= 16
- Работающий сервис PostgreSQL. И определенные переменные окружения необходимые для работы пакета pg.
- Для корректной работы авторизации и аутентификации на основе сессий структура базы данных должна соответствовать представленной.
npm i web-soft-server
Ниже представлен пример использования пакета web-soft-server.
index.js
const fs = require('fs');
const { Server, logger } = require('web-soft-server');
const modules = require('./modules');
const key = fs.readFileSync('private.key');
const cert = fs.readFileSync('cert.crt');
const start = async () => {
try {
const server = new Server({ host: 'localhost', port: 443, cors: false, key, cert, secure: true });
server.start(modules);
} catch (error) {
logger.fatal(error);
}
};
start();
При создании экземпляра класса Server передаём ему модули приложения, пример модуля представлен ниже, и настройки.
modules.js
class Example {
method() {
return { message: 'Hello from server!' };
}
}
module.exports = {
example: {
schema: {
method: {
description: 'Test method for example.',
public: true,
params: {
description: 'Params for test method.',
required: ['param1'],
properties: {
param1: {
type: 'number',
description: 'Param1 is number.'
}
}
},
result: {
description: 'Value that server must return.',
type: 'object',
properties: {
message: {
type: 'string'
}
}
}
}
},
Module: Example
}
};
Интерфейс модуля - ServerModule представлен ниже. Каждый метод модуля получает два параметра:
- data: any
- client: Client
Где data - параметры переданные клиентом серверу согласно спецификации JSON-RPC 2.0.
new Server( [config: ServerConfig] )
Конструктор класса Server. Принимает оснонвые параметры для создания сервера.
start( [modules?: { [name: string]: ServerModule }] ) : void
Метод запускает сервер. Сервер запускается согласно конфигурации и принимает как http, так и WebScoket соединения. Для работы методу передаётся объект с доступными модулями. По умолчанию сервер загружает модуль Introspection, который отдаёт клиенту схему текущего доступного API.
Прекращает приём входящих соединений. И прерывает текущие соединения после указанного в конфигурации интервала времени.
new ConnectionError(meta: ErrorMetaData[, data: any])
Класс расширяет стандартный тип Error.
Код ошибки. Список встроенных ошибок и кодов.
В объект ошибки могут быть вложены дополнительные данные, необходимые для дальнейшего анализа этой ошибки. Тип данных может быть любым, так как не используется внутри пакета.
Сообщение предназначенное исключительно для внутренних нужд сервера или анализа разработчиком. Не будет отправлено в ответе клиенту.
Флаг отвечающий за отправку ошибки в ответе клиенту. По умолчанию: true. Чтобы одновременно отправить ошибку клиенту и сокрыть некоторую информацию используется свойство internal. Если свойство pass установлено в false, клиенту будет отправлено стандартное сообщение о внутренний ошибке сервера.
Идентификатор текущего запроса согласно спецификации JSON-RPC 2.0.
user: User
Пользователь, инициировавший запрос. Определяется если клиент авторизован.
session: Session
Если клиент авторизован, в поле содержится объект с текущей сессией клиента.
Метод для отправки уведомления клиенту. Можно использовать только в случае подключения клиента по протоколу WebSocket. Также следует указать в MethodSchema формат отправляемых данных в поле emit.
client.startSession(user: User): void
Начинает новую сессию для пользователя. Возможно использовать только при запросе по протоколу HTTP.
Удаляет текущую сессию пользователя.
Используется для проверки входящих и исходящих данных сервера.
validator.compile(schema : MethodDataSchema) : (data: any) => boolean
Генерирует и возвращает функцию для валидации данных, согласно переданной схеме.
Вспомогательный объект для взаимодействия с данными пользователей. В основном используется для авторизации/аутентификации.
userService.save(username: string, hashPassword: string): Promise<UserRole>
Добавляет нового пользователя в базу данных.
userService.getByUsername(username: string): Promise<User>
Возвращает информацию о пользователе из базы данных.
userService.updatePassword(username: string, password: string): Promise<UserRole>
Меняет пароль пользователя на новый.
Сессии используют данные cookie пользователя, куда помещается уникальный ключ в формате uuid4.
sessionService.restoreSession(request: IncomingMessage): Promise<Session>
Восстанавливает сессию из базы дынных на основе coockie данных запроса клиента.
sessionService.startSession(request: IncomingMessage, response: ServerResponse, username: string): Promise<Session>
Создаёт новую сессию для клиента. Сохраняет уникальный ключ сессиии в cookie.
sessionService.endSession(request: IncomingMessage, response: ServerResponse): Promise<Session>
Удаляет сессию клиента из базы данных, если сессия будет обнаружена.
logger.setSettings(settings: LoggerSettings): void
Установка настроек для управления выводом различных типов сообщений.
logger.setTransport(transport: LoggerTransport): void
Замена консольного транспорта по умолчанию.
Вывод информационного сообщения.
Вывод отладочного сообщения.
Вывод предупреждения.
Сообщение с информацией о взаимодействии с базой данных.
Сообщение об ошибке.
Сообщение о критической ошибке, приводящей к перезапуску сервера.
Вспомогательный объект для взаимодействия с базой данных PostgreSQL. Имеет несколько заготовленных методов для упрощённого использование CRUD операций, а также метод для написания произвольных запросов.
Метод для отправки произвольных запросов в базу данных. Первый параметр отвечает за текст SQL запроса, второй за список параметров запроса. Возвращает список строк.
database.insert(table: string, data: DatabaseData[, returning: Array]): Promise
Метод операции вставки в базу данных. Параметр data задаёт значения вставляемого в базу данных кортежа, returning позволяет перечислить значения, которые необходимо вернуть после успешной вставки.
database.select(table: string[[[[, fields: Array], conditions: DatabaseData], orderFields: Array], itemsOnPage: number, page: number]): Promise<any[]>
Метод операции выборки из базы данных. Параметр conditions задаёт значения условий, согласно которым будет выбран кортеж, fields - поля которые должны присутствовать в выборке, orderFields - поля по которым должна быть отсортирована выборка, itemsOnPage - количество элементов на странице выборки и page - номер необходимой страницы.
database.update(table: string, delta: DatabaseData, conditions: DatabaseData[, returning: Array]): Promise<any[]>
Метод операции обновления кортежа в базе данных. Параметр delta задаёт значения, которые должны быть изменены, conditions задаёт значения условий, согласно которым будет выбран кортеж, returning позволяет перечислить значения, которые необходимо вернуть после успешной операции изменения.
database.delete(table: string, conditions: DatabaseData[, returning: Array]): Promise<any[]>
Метод операции удаления кортежа из базы данных. Параметр conditions задаёт значения условий, согласно которым будет выбран кортеж, returning позволяет перечислить значения, которые необходимо вернуть после успешной операции удаления.
Добавляет новый тип ошибки в словарь ошибок используемых сервером. Регистрировать новый тип ошибки необходимо, если клиент использует метод getErrors() стандартного модуля Introspection.
Name | Type | Description |
---|---|---|
[port] | number | Порт для прослушивания сервером. По умолчанию: 80 |
[host] | string | IP адрес. По умолчанию: localhost |
[cors] | boolean | True - разрешить запрос из любых источников, иначе запретить. По умолчанию: true |
[serverCloseTimeout] | number | Количество миллисекуд, которое сервер ожидает перед принудительным закрытием соединений. По умолчанию: 500 |
[secure] | boolean | Нужно ли использовать защищённое HTTPS соединение. При установке значения true необходимо передать параметры key и cert. По умолчанию: false |
[key] | string | Приветный ключ. |
[cert] | string | Сертификат. |
Name | Type | Description |
---|---|---|
schema | { [method: string]: MethodSchema } | Схема с параметрами метода |
Module | Class | Класс модуля. Инстанцированием объектов класса занимается сервер. |
Name | Type | Description |
---|---|---|
[public] | boolean | Доступность метода для неавторизованных пользователей. По умолчанию: false |
[description] | string | Описание метода. По умолчанию: '' |
[params] | MethodDataSchema | Схема параметров метода. |
[result] | MethodDataSchema | Схема данных, возвращаемых методом. |
[emit] | MethodDataSchema | Схема данных, отправляемых методом при срабатывании события. Присутствие данного параметра является индикатором того, что при вызове метода пользователь подписывается на событие, соответственно должно использоваться WebSocket соединение. |
[roles] | Array | Массив со списком ролей пользователей, которым доступен вызов метода. При пустом массиве вызов метода разрешён всем пользователям. По умолчанию: []. |
[transport] | 'http' | 'ws' |
Схема данных отправляемых или принимаемых сервером. Испольуется в том числе и для валидации данных отправляемых и принимаемых сервером. Для валидации используется Ajv JSON schema validator со спецификацией JSON Schema. Здесь описаны основные параметры, полных список доступных свойств можно найти на странице.
Name | Type | Description |
---|---|---|
[type] | string | Тип данных. По умолчанию: object |
description? | string | Дополнительня информация о данных. |
[required] | Array | При указании типа данных object, можно перечислить свойства, который обязательно должны быть представлены в объекте данных. |
[properties] | { [property: string]: MethodDataSchema } | При указании типа данных object, перечисляются возможные поля объекта, каждое поле описывается по аналогичной схеме данных. |
[items] | MethodDataSchema | При указании типа данных array, описывается аналогичная схема данных для элементов массива. |
[additionalProperties] | MethodDataSchema | При указании типа данных object, указывается возможность присутствия в объекте дополнительных свойсв. True - дополнительные свойства, не описанные в схеме могут присутствовать. По умолчанию: false. |
Name | Type | Description |
---|---|---|
username | string | Имя пользователя. |
password | string | Пароль. При использовании модуля Авторизации/Аутентификации сервера, хранится ввиде хэша. |
role | string | Роль пользователя. По умолчанию: user |
createdTime | string | Время добавления пользователя в базу данных. |
Name | Type | Description |
---|---|---|
role | string | Роль пользователя. По умолчанию: user |
createdTime | string | Время добавления пользователя в базу данных. |
Name | Type | Description |
---|---|---|
username | string | Имя пользователя, для которого создаётся сессия. |
token | string | Уникальный ключ сессии. |
createdTime | string | Время создание сессии. |
Name | Type | Description |
---|---|---|
[info] | boolean | Включает вывод информационных сообщений. |
[debug] | boolean | Включает вывод отладочных сообщений. |
[warn] | boolean | Включает вывод предупреждающих сообщений. |
[error] | boolean | Включает вывод сообщений об ошибках. |
[fatal] | boolean | Включает вывод сообщений о критических ошибках. |
[sql] | boolean | Включает вывод сообщений о взаимодействии с базой данных. |
Интерфейс, которым должен обладать траспорт для вывода логов. Logger будет вызывать метод log у траспорта и передавать ему объект с сообщением.
Name | Type | Description |
---|---|---|
log | (data: LoggerMessage) => void | Отправляет сообщение в поток вывода. |
Name | Type | Description |
---|---|---|
type | string | Тип сообщения. |
message | string | Текст сообщения. |
[stack] | string | Stack trace ошибки. Передаётся только для типов сообщений error и fatal |
Name | Type | Description |
---|---|---|
code | number | Код ошибки. |
message | string | Стандартное сообщение об ошибке. |
[internal] | string | Сообщение об ошибке для внутреннего использования. |
Name | Type | Description |
---|---|---|
[key: string] | number | string | boolean | Объект с данными для базы данных. Может использовать для добавления данных и задания условий поиска. Должен состоять из строковых ключей и значений указанных типов. В случае если объект задаёт условия поиска, строковые значения полей могут дополняться в начале следующими операторами сравнения: >=, <=, <>, >, <. |
При добавление и определении иных типов ошибок необходимо свериться со спецификацией JSON-RPC 2.0.
Error | Code | Message |
---|---|---|
INVALID_REQUEST | -32600 | The JSON sent is not a valid Request object. |
METHOD_NOT_FOUND | -32601 | The method does not exist / is not available. |
INVALID_PARAMS | -32602 | Invalid method parameter(s). |
INTERNAL_ERROR | -32603 | Internal server error. |
PARSE_ERROR | -32700 | Invalid JSON was received by the server. |
AUTHENTICATION_FAILED | -40300 | Authentication failed. |
UNAUTHORIZED | -40401 | Authentication credentials required. |
FORBIDDEN | -40403 | Permission denied. |
DATA_CONFLICT | -40409 | Conflict error. |
DATA_ERROR | -40410 | Data error. |
SERVICE_UNAVAILABEL | -40503 | Service temporarily unavailable. |
INVALID_HTTP_METHOD | -50400 | Request method must be POST. |
BAD_TRASPORT | -50405 | Inappropriate transport protocol. |
Простой модуль авторизации/аутентификации/регистрации пользователей. Используется аутентификация по паролю и сессии для сохранения состояния.
auth.register({ username: string, password: string }, client: Client): Promise<{username: string, role: string, createdTime: string}>
Регистрация нового пользователя.
auth.login({ username: string, password: string }, client: Client): Promise<{username: string, role: string, createdTime: string}>
Аутентификация пользователя по паролю.
auth.logout(data: any, client: Client): void
Удаление сессии пользователя.
auth.me(data: any, client: Client): Promise<{username: string, role: string, createdTime: string}>
Получение информации о текущем пользователе.
auth.changePassword({ username: string, oldPassword: string, newPassword: string }, client: Client): Promise<{username: string, role: string, createdTime: string}>
Смена пароля пользователя.
Модуль предоставляет функции для получения схемы API сервера, а также списка ошибок, встроенных в пакет и зарегистрированных пользователем. Основное назначение модуля - генерация API вызовов на стороне клиента, примером является пакет web-soft-client.
introspection.getModules() : { [name: string]: ServerModule }
Возвращает схему API сервера.
Возвращает словарь, содержащий типы ошибок, используемых сервером.
- label - сокращённое наименование ошибки
- code - код ошибки
- message - сообщение ошибки