This model is a main entry point for a UnityBase server application.
Application
In terms of UnityBase application is defined by:
- configuration (ubConfig.json by default): file what describe settings for http server, logging, authorization methods, Domain, etc. See server config json schema for full description;
package.json
- npm/yarn configuration used to give information to package manager that allows it to identify the project as well as handle the project's dependencies
Inside package.json
the main field
is a primary entry point of UnityBase application. In most case entry point
file content is:
const UB = require('@unitybase/ub')
UB.start()
Application initialization
once on server startup (single thread mode, http server do not accent connections)
This stage is added in UB@5.18.0 to allow custom Domain transformation before any other steps is performed.
Just after UB starts in server mode it creates a single-thread JavaScript runtime and use a @unitybase/ub/metadataTransformation.js
script as an entry point for Domain loading. Script loads all *.meta
and *.meta.lang
files into memory, merge files with the same names
and calls a _hookMetadataTransformation.js
hook from models folders (if available) with two parameters (domainJSON, serverConfig)
Metadata transformation hook can mutate a Domain JSON, for example - adds additional attributes to the entities and lang files, etc
Files are merged and hooks are called in order models appears in application.domain.models
server config section.
After all hooks are called resulting domainJSON is passed back to UB to initialize a Domain classes.
UB server:
- initialize internal Domain
- evaluate an application entry-point script (see UB.js below)
- initialize ELS (since all models scripts is evaluated on this point all entity-level methods and endpoints are in Domain, so server can build an access matrix for methods and roles)
UB server switches to multi-thread mode and can accept HTTP requests
JS working thread (multi-thread mode)
In multi-thread mode UB uses a thread pool of size threadPoolSize
from ubConfig.
Threads in pool are created lazy - in case there is no free thread to accept an incoming request new thread is spawned
until thread poll is not full.
Every new working thread use UB.js
as entry point.
UB.js script content is embedded into executable, but it sources is also available in @unitybase/stubs/UB.js
.
The task of UB.js script is to require and run an application entry point script (main from package.json).
As described above entry point script will execute a UB.start() and
UB.start method of @unitybase/ub
package will perform a steps below
(actually for every working thread):
- for each model from application.domain.models
folders (except ones marked as _public_only_
)
load a model (see below)
- register build-in UnityBase endpoints
- emit App.domainIsLoaded event
Model
Server-side
Model is a commonJS module with logically grouped set of entities + server side code + client-side code. In the application config (ubConfig.json) application.domain.models section contains an array of models, required by application.
Model is loaded in server thread memory(in order they defined in application.domain.models
config section) in three steps:
- entity (global objects) are created for all
*.meta
files from this model require
is called for all*.js
files paired with*.meta
require
is called for model entry point defined inpackage.json
placed in the model folder
Model package.json
can contain engines.ub
section - a minimal version of UB server for this model.
Starting from UB@5.22.15 server throws if it's version is less than specified in engine.ub
.
The only supported semantic is >=
. Example:
{
"name": "@unitybase/uba",
"engines": {
"ub": ">=5.22.15"
}
}
To simplify a ubConfig model package.json
can contain config.ubmodel
section what describe the
model name and (optionally) ``"isPublic": true` for "browser-only" model
"config": {
"ubmodel": {
"name": "UBS"
}
},
for "browser-only" model:
"config": {
"ubmodel": {
"name": "adminui-pub",
"isPublic": true
}
},
For such models only path to model should be added to the application.domain.models
section of ubConfig.json:
"application": {
...
"domain": {
"models": [
...
{
"path": "./node_modules/@unitybase/ubs"
},
Client-side (adminUI)
Model can contain a "browser-side" part. In this case model package.json
should contains browser
section
what point to the model initialization script for browser:
- In case model is a published module (placed in the node_modules folder) path should be relative to the
package.json
:
"browser": "./public/initModel.js"
- or for dev/prod scripts
"browser": {
"dev": "./public/devEntryPoint.js"
"prod": "./public/dist/modelBundle.js"
}
- In case model is in
models
folder p[ath must be absolute
"browser": "/clientRequire/models/TST/initModel.js",
Endpoints
UnityBase comes with simple one-level routing. App.registerEndpoint method will add a handlers functions for a first level of routing:
const fs = require('fs')
/**
* Write a custom request body to file FIXTURES/req and echo file back to client
* @param {THTTPRequest} req
* @param {THTTPResponse} resp
*/
function echoToFile(req, resp) {
fs.writeFileSync(FIXTURES + 'req', req.read('bin'))
resp.statusCode = 200
resp.writeEnd(fs.readFileSync(FIXTURES + 'req', {encoding: 'bin'}))
}
App.registerEndpoint('echoToFile', echoToFile)
More deep routing can be implemented inside the endpoint handler, as we did inside build-in UnityBase endpoints
JSON schemas
@unitybase/ub/public/schemas
folder contains JSON schemas for server config, entity meta file and scheduler config.
It's a good idea to configure your IDE for JSON schema support.
See WebStorm IDE configuratuion manual
Classes
Submodules
Members
# App static
Application instance
Name | Type | Description |
---|---|---|
App | ServerApp |
# ESecurityException static
Server-side Security exception. Throwing of such exception will trigger
Session.securityViolation
event
Name | Type | Description |
---|---|---|
ESecurityException | ESecurityException |
# i18nExtend static
Merge localizationObject to UB.i18n
const UB = require('@unitybase/ub')
UB.i18nExtend({
"en": {yourMessage: "yourTranslationToEng", ...},
"uk": {yourMessage: "yourTranslationToUk", ...},
....
})
// if logged-in user language is `en` will output "yourTranslationToEng"
console.log(UB.i18n(yourMessage))
// will output "yourTranslationToUk"
console.log(UB.i18n(yourMessage, 'uk'))
# isServer static
If we are in UnityBase server scripting (both -f or server thread) this property is true, if in browser - undefined or false. Use it for check execution context in scripts, shared between client & server. To check we are in server thread use process.isServer
# loadLegacyModules static
For UB < 4.2 compatibility - require all non - entity js
in specified folder add its sub-folder (one level depth),
exclude modules
and node_modules
sub-folder's.
From 'public' sub-folder only cs*.js are required.
To be called in model index.js as such:
const UB = require('@unitybase/ub') UB.loadLegacyModules(__dirname)
For new models we recommend to require non-entity modules manually
# ns deprecated static
Creates namespaces to be used for scoping variables and classes so that they are not global.
Try to avoid namespaces - instead create a module and use require()
UB.ns('DOC.Report');
DOC.Report.myReport = function() { ... };
# registerMixinModule static
A way to add additional mixins into domain
# Session static
Information about the logged-in user
Name | Type | Description |
---|---|---|
Session | Session |
Methods
# DataStore (entityCode: string) → TubDataStore static
Construct new data store
Arguments:
entityCode
: string
# i18n (msg: string, args: *) → * static
Return locale-specific resource from it identifier. Resources are defined by UB.i18nExtend
In case firs element of args is a string with locale code supported by application then translate to specified locale, in other case - to locale of the current user (user who done the request to the server)
Localized string can be optionally formatted by position args
Arguments:
msg
: stringMessage to translate
args
: *Format args
UB.i18nExtend({
en: { greeting: 'Hello {0}, welcome to {1}' },
uk: { greeting: 'Привіт {0}, ласкаво просимо до {1}' }
})
UB.i18n('greeting', 'Mark', 'Kiev') // in case current user language is en -> "Hello Mark, welcome to Kiev"
UB.i18n('greeting', 'uk', 'Mark', 'Kiev') // in case ru lang is supported -> "Привіт Mark, ласкаво просимо до Kiev"
# Repository (entityName: string, cfgopt: object, connectionopt: SyncConnection) → ServerRepository static
Create new instance of ServerRepository
Arguments:
entityName
: stringcfg
: objectconnection
: SyncConnectionPass in case of remote UnityBase server connection.
# initializeDomain () inner
# normalizeEnums () inner
# ns (namespacePath) → object inner
Arguments:
namespacePath
:
# start () inner
Initialize UnityBase application:
- create namespaces (global objects) for all
*.meta
files from domain - require all packages specified in config
application.domain.models
- apply a server-side i18n JSONs from models serverLocale folder
- emit App.domainIsLoaded event
- initialize BLOB stores
- emit App.applicationReady event
- register build-in UnityBase endpoints
# UBAbort (messageopt: string, args: any) inner
Server-side Abort exception. To be used in server-side logic in case of HANDLED exception. These errors logged using "Error" log level to prevent unnecessary EXC log entries
// UB client will show message inside <<<>>> to user (and translate it using UB.i18n)
const UB = require('@unitybase/ub')
throw new UB.UBAbort('<<<textToDisplayForClient>>>')
// In case, client-side message shall be formatted:
throw new UB.UBAbort('<<<file_not_found>>>', 'bad_file.name')
// The "file_not_found" i18n string on client should be like `'File "{0}" is not found or not accessible'
// Format args can be translated by assing a :i18n modifier to template string: `'File "{0:i18n}" is not found or not accessible'
// In case message should not be shown to the end used by ub-pub globalExceptionHandler `<<<>>>` can be omitted
throw new UB.UBAbort('wrongParameters')
Types
# ubBlobHistoryAttrs inner
Properties
# ubMigrationAttrs inner
Properties
# ubVersionAttrs inner
Properties