Skip to content

Latest commit

 

History

History
658 lines (385 loc) · 31.5 KB

README-RU.md

File metadata and controls

658 lines (385 loc) · 31.5 KB

web-soft-server

Пакет для создания 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 - параметры переданные клиентом серверу согласно спецификации JSON-RPC 2.0.

Классы

Server

new Server( [config: ServerConfig] )

Конструктор класса Server. Принимает оснонвые параметры для создания сервера.

start( [modules?: { [name: string]: ServerModule }] ) : void

Метод запускает сервер. Сервер запускается согласно конфигурации и принимает как http, так и WebScoket соединения. Для работы методу передаётся объект с доступными модулями. По умолчанию сервер загружает модуль Introspection, который отдаёт клиенту схему текущего доступного API.

close() : void

Прекращает приём входящих соединений. И прерывает текущие соединения после указанного в конфигурации интервала времени.

ConnectionError

new ConnectionError(meta: ErrorMetaData[, data: any])

Класс расширяет стандартный тип Error.

code: number

Код ошибки. Список встроенных ошибок и кодов.

data: any

В объект ошибки могут быть вложены дополнительные данные, необходимые для дальнейшего анализа этой ошибки. Тип данных может быть любым, так как не используется внутри пакета.

internal: string

Сообщение предназначенное исключительно для внутренних нужд сервера или анализа разработчиком. Не будет отправлено в ответе клиенту.

pass: boolean

Флаг отвечающий за отправку ошибки в ответе клиенту. По умолчанию: true. Чтобы одновременно отправить ошибку клиенту и сокрыть некоторую информацию используется свойство internal. Если свойство pass установлено в false, клиенту будет отправлено стандартное сообщение о внутренний ошибке сервера.

Client

id: number

Идентификатор текущего запроса согласно спецификации JSON-RPC 2.0.

user: User

Пользователь, инициировавший запрос. Определяется если клиент авторизован.

session: Session

Если клиент авторизован, в поле содержится объект с текущей сессией клиента.

client.emit(event: string, data: any): void

Метод для отправки уведомления клиенту. Можно использовать только в случае подключения клиента по протоколу WebSocket. Также следует указать в MethodSchema формат отправляемых данных в поле emit.

client.startSession(user: User): void

Начинает новую сессию для пользователя. Возможно использовать только при запросе по протоколу HTTP.

client.deleteSession(): void

Удаляет текущую сессию пользователя.

Объекты сервисы

validator

Используется для проверки входящих и исходящих данных сервера.

validator.compile(schema : MethodDataSchema) : (data: any) => boolean

Генерирует и возвращает функцию для валидации данных, согласно переданной схеме.

userService

Вспомогательный объект для взаимодействия с данными пользователей. В основном используется для авторизации/аутентификации.

userService.save(username: string, hashPassword: string): Promise<UserRole>

Добавляет нового пользователя в базу данных.

userService.getByUsername(username: string): Promise<User>

Возвращает информацию о пользователе из базы данных.

userService.updatePassword(username: string, password: string): Promise<UserRole>

Меняет пароль пользователя на новый.

sessionService

Сессии используют данные 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

logger.setSettings(settings: LoggerSettings): void

Установка настроек для управления выводом различных типов сообщений.

logger.setTransport(transport: LoggerTransport): void

Замена консольного транспорта по умолчанию.

logger.info(...data: any[]): void

Вывод информационного сообщения.

logger.debug(...data: any[]): void

Вывод отладочного сообщения.

logger.warn(...data: any[]): void

Вывод предупреждения.

logger.sql(...data: any[]): void

Сообщение с информацией о взаимодействии с базой данных.

logger.error(error: Error): void

Сообщение об ошибке.

logger.fatal(error: Error): void

Сообщение о критической ошибке, приводящей к перезапуску сервера.

database

Вспомогательный объект для взаимодействия с базой данных PostgreSQL. Имеет несколько заготовленных методов для упрощённого использование CRUD операций, а также метод для написания произвольных запросов.

database.query(text: string[, params: Array]): Promise<any[]>

Метод для отправки произвольных запросов в базу данных. Первый параметр отвечает за текст 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 позволяет перечислить значения, которые необходимо вернуть после успешной операции удаления.

Функции

registerError(label: string, code: number, [message: string]): { code: number; message: string }

Добавляет новый тип ошибки в словарь ошибок используемых сервером. Регистрировать новый тип ошибки необходимо, если клиент использует метод getErrors() стандартного модуля Introspection.

Интерфейсы

ServerConfig

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 Сертификат.

ServerModule

Name Type Description
schema { [method: string]: MethodSchema } Схема с параметрами метода
Module Class Класс модуля. Инстанцированием объектов класса занимается сервер.

MethodSchema

Name Type Description
[public] boolean Доступность метода для неавторизованных пользователей. По умолчанию: false
[description] string Описание метода. По умолчанию: ''
[params] MethodDataSchema Схема параметров метода.
[result] MethodDataSchema Схема данных, возвращаемых методом.
[emit] MethodDataSchema Схема данных, отправляемых методом при срабатывании события. Присутствие данного параметра является индикатором того, что при вызове метода пользователь подписывается на событие, соответственно должно использоваться WebSocket соединение.
[roles] Array Массив со списком ролей пользователей, которым доступен вызов метода. При пустом массиве вызов метода разрешён всем пользователям. По умолчанию: [].
[transport] 'http' 'ws'

MethodDataSchema

Схема данных отправляемых или принимаемых сервером. Испольуется в том числе и для валидации данных отправляемых и принимаемых сервером. Для валидации используется 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.

User

Name Type Description
username string Имя пользователя.
password string Пароль. При использовании модуля Авторизации/Аутентификации сервера, хранится ввиде хэша.
role string Роль пользователя. По умолчанию: user
createdTime string Время добавления пользователя в базу данных.

UserRole

Name Type Description
role string Роль пользователя. По умолчанию: user
createdTime string Время добавления пользователя в базу данных.

Session

Name Type Description
username string Имя пользователя, для которого создаётся сессия.
token string Уникальный ключ сессии.
createdTime string Время создание сессии.

LoggerSettings

Name Type Description
[info] boolean Включает вывод информационных сообщений.
[debug] boolean Включает вывод отладочных сообщений.
[warn] boolean Включает вывод предупреждающих сообщений.
[error] boolean Включает вывод сообщений об ошибках.
[fatal] boolean Включает вывод сообщений о критических ошибках.
[sql] boolean Включает вывод сообщений о взаимодействии с базой данных.

LoggerTransport

Интерфейс, которым должен обладать траспорт для вывода логов. Logger будет вызывать метод log у траспорта и передавать ему объект с сообщением.

Name Type Description
log (data: LoggerMessage) => void Отправляет сообщение в поток вывода.

LoggerMessage

Name Type Description
type string Тип сообщения.
message string Текст сообщения.
[stack] string Stack trace ошибки. Передаётся только для типов сообщений error и fatal

ErrorMetaData

Name Type Description
code number Код ошибки.
message string Стандартное сообщение об ошибке.
[internal] string Сообщение об ошибке для внутреннего использования.

DatabaseData

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.

Готовые модули

AuthModule

Простой модуль авторизации/аутентификации/регистрации пользователей. Используется аутентификация по паролю и сессии для сохранения состояния.

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}>

Смена пароля пользователя.

Introspection

Модуль предоставляет функции для получения схемы API сервера, а также списка ошибок, встроенных в пакет и зарегистрированных пользователем. Основное назначение модуля - генерация API вызовов на стороне клиента, примером является пакет web-soft-client.

introspection.getModules() : { [name: string]: ServerModule }

Возвращает схему API сервера.

introspection.getErrors() : { [label: string]: {code: number, message: string} }

Возвращает словарь, содержащий типы ошибок, используемых сервером.

  • label - сокращённое наименование ошибки
  • code - код ошибки
  • message - сообщение ошибки