SGApps Server - very fast NodeJS WebServer
A network solution for web applications.
Since this application is fully compatible with nodejs-mvc, I decided to replace nodejs-mvc with this new approach. SGApps Server is completely new solution, that will be improved continuously thats why I will work on this project instead of nodejs-mvc
by Sergiu Gordienco < sergiu.gordienco@sgapps.io >
Features
- ๐ Much Faster with common used Interface
- ๐ป Pretty Logger Integrated
- ๐๏ธ AccessLogs ( Combined )
- ๐ GoAccess Statistics Support ( v1.5.6 )
- ๐ AWSTats Statistics Support
- ๐ TypeScript Typings ( Intellisense Support )
- ๐ support with MVC Framework
Authors
- Gordienco Sergiu < sergiu.gordienco@sgapps.io >
License
the license is Apache-2.0, so one of the requirements is to include reference to this project
Samples
Simple Integration ( Similar to ExpressJS )
const { SGAppsServer } = require('sgapps-server');
const app = new SGAppsServer();
app.get('/', function (request, response) {
response.send('hello world')
});
app.server().listen(8080, () => {
app.logger.log('Server is running on port 8080');
});
Example of Integration with SessionSupport ๐ฆ
// ========================================
// Start your ๐ Web-Server app Extended
// ========================================
const { SGAppsServer } = require('sgapps-server');
const app = new SGAppsServer();
app.get('/', function (request, response) {
response.send('hello world session#' + request.session.id);
})
app.whenReady.then(() => {
app.SessionManager.cookie = 'ssid';
app.SessionManager.SESSION_LIFE = 120; // seconds
app.server().listen(8080, () => {
app.logger.log('Server is running on port 8080');
});
}, app.logger.error);
Example of Integration with AccessLogs for AWStats or GoAccess
const { SGAppsServer } = require('sgapps-server');
const app = new SGAppsServer({
decorators: [
require('sgapps-server/decorators/access-logger')
]
});
app.AccessLoggerPaths['default'] = {
isEnabled: true,
path: configuration.database.filesystem.logs + 'default/{year}/{month}/data-{worker-id}.log'
};
app.whenReady.then(() => {
app.server().listen(8080, () => {
app.logger.log('Server is running on port 8080');
});
}, app.logger.error);
Example Advanced of Integration with AccessLogs for AWStats or GoAccess
const { SGAppsServer } = require('sgapps-server');
const app = new SGAppsServer({
decorators: [
require('sgapps-server/decorators/access-logger')
]
});
app.AccessLoggerPaths['default'] = {
isEnabled: true,
// modify the row
waitAllHandlers: true,
path: configuration.database.filesystem.logs + 'default/{year}/{month}/data-{worker-id}.log',
handle: function (data) {
// used for updating of filtering data
console.info("LOGGER Data", data);
return data.match(/\.txt\"/) ? null : data;
}
};
app.get(/^\/api\//, function () {
// log all request from api path into separate file
request.AccessLoggerPaths['api'] = {
isEnabled: true,
path: 'api/access.log'
}
})
app.whenReady.then(() => {
app.server().listen(8080, () => {
app.logger.log('Server is running on port 8080');
});
}, app.logger.error);
Full API documentation can be found on
API
Table of Contents
- SGAppsServerRequestSession
- TemplateManager
- SGAppsServerRequest
- routeMatch
- SGAppsServerResponse
- TemplateManagerRenderOptions
- TemplateManagerViewer
- TemplateManagerTemplate
- SGAppsServerEmail
- SGAppsSessionManagerOptions
- SGAppsServerRequestSessionCache
- MountUpdatedURL
- FaceboxTemplate
- SGAppsServerRequestCookie
- SGAppsServerDecoratorsLibrary
- SGAppsServerErrorCallBack
- SGAppsServerErrorOnlyCallback
- FSLibrary
- SGAppsServerShared
- SGAppsServerRequestFile
- SGAppsServerRequestPostDataItem
- SGAppsServerDecorator
- SGAppsServer
- CookiesManager
- _server
- _decorators
- TemplateManager
- _options
- STATUS_CODES
- shared
- logger
- mountPath
- SessionManager
- _fs
- _path
- EXTENSIONS
- _requestListeners
- MAX_POST_SIZE
- whenReady
- handleRequest
- handleErrorRequest
- handleStaticRequest
- handle
- server
- use
- post
- get
- head
- put
- trace
- delete
- options
- connect
- patch
- all
- finalHandler
- handlePostData
- LoggerBuilder
- RequestPathStructureMap
- SGAppsServerDictionary
- RequestPathStructure
- RequestHandler
- SGAppsServerOptions
- SGAppsSessionManager
- RequestSessionDecorator
- SGAppsServerDictionaryRunCallBack
- request
- request
- LoggerBuilderPrompt
- SGAppsServerHandlerPostData
SGAppsServerRequestSession
Type: function (request, options)
request
SGAppsServerRequestoptions
SGAppsSessionManagerOptions
_created
Type: number
_ip
Type: string
_confirmed
Session was received from previously saved cookie
Type: boolean
_id
Type: string
_options
Type: SGAppsSessionManagerOptions
data
Type: object
destroy
Type: function ()
TemplateManager
Type: function (options)
_options
Type: object
_fs
FSLibrary
_viewer
Type: TemplateManagerViewer
_env
templateExists
Type: function (templateName): boolean
templateName
string
remove
Type: function (templateName)
templateName
string
add
Type: function (templateName, filePath)
addList
Type: function (templates)
get
Type: function (templateName): TemplateManagerTemplate
templateName
string
render
Type: function (response, templateName, vars)
response
SGAppsServerResponsetemplateName
stringvars
Object<string, any>?
SGAppsServerRequest
Type: function (request, server)
request
IncomingMessageserver
SGAppsServer
request
Type: IncomingMessage
_postDataBuffer
post data buffer cache
Type: Buffer
getMountUpdatedUrl
Type: function (url): MountUpdatedURL
url
string
urlInfo
Type: object
original
stringorigin
stringdomain
string full domain of urldomain_short
string domain without "www."pathname
string url's pathnamereqQuery
string url's query from '?'protocol
string url.split('://')[0]url
stringurl_p
stringisIp
string domain or Ip
query
Type: object
mountPath
Type: string
body
Type: object
bodyItems
Type: Array<SGAppsServerRequestPostDataItem>
cookies
Type: SGAppsServerRequestCookie
MAX_POST_SIZE
Type: number
Examples:
// changing max post size to 4Mb
request.MAX_POST_SIZE = 4 * 1024 * 1024;
// reset max post size to global value
request.MAX_POST_SIZE = -1;
files
Type: Object<string, Array<SGAppsServerRequestFile>>
fileItems
Type: Array<SGAppsServerRequestFile>
_destroy
Array of functions to be called on response end
params
Array of functions to be called on response end
Type: SGAppsServerRequest.RequestParams
_flags
Array of functions to be called on response end
Type: object
complete
boolean The message.complete property will be true if a complete HTTP message has been received and successfully parsed.aborted
boolean The message.aborted property will be true if the request has been aborted.closed
boolean Indicates that the underlying connection was closed._DEBUG_MAX_HANDLER_EXECUTION_TIME
number? define a bigger request timeout
_parseDeepFieldName
Automatically used procedure for parsing formData field name if option server._options._REQUEST_FORM_PARAMS_DEEP_PARSE = true
. it's by default enabled but can be disabled when needed
Type: function (container, fieldName, fieldData, options)
container
objectfieldName
stringfieldData
anyoptions
object?options.transform2ArrayOnDuplicate
boolean (optional, defaultfalse
)
Examples:
paramsContainer = {};
request._parseDeepFieldName(paramsContainer, 'test[arr][data]', 2);
request._parseDeepFieldName(paramsContainer, 'test[arr][]', new Date());
request._parseDeepFieldName(paramsContainer, 'test[arr][]', 2);
request._parseDeepFieldName(paramsContainer, 'test[data]', 2);
// if _debug enabled warns will be emitted
// [Warn] [Request._parseDeepFieldName] Writing Array field "test[arr][]" into a object
// [Warn] [Request._parseDeepFieldName] Overwriting field "test[data]" value
console.log(paramsContainer)
{
"test": {
"arr": {
"1": "2021-02-12T21:23:01.913Z",
"2": 2,
"data": 2
},
"data": 2
}
}
paramsContainer = {};
request._parseDeepFieldName(paramsContainer, 'test[arr][]', new Date());
request._parseDeepFieldName(paramsContainer, 'test[arr][]', 2);
request._parseDeepFieldName(paramsContainer, 'test[arr][data]', 2);
request._parseDeepFieldName(paramsContainer, 'test[data]', 2);
// if _debug enabled warns will be emitted
// [Warn] [Request._parseDeepFieldName] Converting array to object due incorrect field "test[arr][data]" name
console.log(paramsContainer)
{
"test": {
"arr": {
"0": "2021-02-12T21:34:47.359Z",
"1": 2,
"data": 2
},
"data": 2
}
}
paramsContainer = {};
request._parseDeepFieldName(paramsContainer, 'test[arr][]', new Date());
request._parseDeepFieldName(paramsContainer, 'test[arr][]', 2);
request._parseDeepFieldName(paramsContainer, 'test[data]', 2);
console.log(paramsContainer)
{
"test": {
"arr": [
"2021-02-12T21:26:43.766Z",
2
],
"data": 2
}
}
session
Type: SGAppsServerRequestSession
postData
request's post received data
RequestParams
Type: (Object<(string | number), string> | Array<string>)
routeMatch
Type: function (route, url, strictRouting, _cache)
route
RequestPathStructureurl
stringstrictRouting
boolean_cache
object
SGAppsServerResponse
Type: function (response, server)
response
ServerResponseserver
SGAppsServer
response
Type: ServerResponse
pipeFile
Type: function (filePath, callback)
filePath
stringcallback
SGAppsServerErrorOnlyCallback represents aFunction(Error)
send
Type: function (data, options)
sendError
Type: function (error, options)
_destroy
Array of functions to be called on response end
redirect
if it returns false
than the action was not possible
Type: function (url, options)
_flags
Array of functions to be called on response end
Type: object
finished
boolean will be true if response.end() has been called.sent
boolean Is true if all data has been flushed to the underlying system, immediately before the 'finish' event is emitted.closed
boolean Indicates that the the response is completed, or its underlying connection was terminated prematurely (before the response completion).
pipeFileStaticCallback
Type: Function
error
Error
pipeFileStatic
Type: function (filePath, fileName, callback, options)
filePath
stringfileName
stringcallback
SGAppsServerResponse.pipeFileStaticCallbackoptions
object?
sendStatusCode
Type: function (statusCode)
statusCode
number
TemplateManagerRenderOptions
Type: object
TemplateManagerViewer
Type: function (options)
_facebox
Type: FaceboxTemplate
_debug
Type: boolean
_env
renderCode
Type: function (code, vars, virtualFilePath, callback)
render
Type: function (response, view, vars)
response
SGAppsServerResponseview
TemplateManagerTemplatevars
Object<string, any>
TemplateManagerTemplate
Type: object
SGAppsServerEmail
Type: function (config)
config
SGAppsServerEmail.Config optional configuration object
Example:
Example:
var Email = require('path/to/email').Email
var myMsg = new Email(
{ from: 'me@example.com'
, to: 'you@example.com'
, subject: 'Knock knock...'
, body: "Who's there?"
})
myMsg.send(function(err){
...
})
send
Send email
Type: function (callback)
callback
SGAppsServerEmail.Callback
options
get message options
Type: object
timeout
number
encodedBody
getter generate encoded body
Type: string
msg
getter generate all email structure
Type: string
valid
check if email is valid
Type: function (callback)
callback
SGAppsServerEmail.Callback
Config
Email : Sends email using the sendmail command.
Note: sendmail must be installed: see http://www.sendmail.org/
Type: object
to
(Array<string> | string) Email address(es) to which this msg will be sentdebug
boolean?from
string? Email address from which this msg is sent. If not set defaults to theexports.from
global setting.replyTo
string? Email address to which replies will be sent. If not set defaults tofrom
cc
(string | Array<string>)? Email address(es) who receive a copybcc
(string | Array<string>)? Email address(es) who receive a blind copysubject
string The subject of the emailbody
string The message of the emailbodyType
string? Content type of body. Only valid option is 'html' (for now). Defaults to text/plain.altText
string? IfbodyType
is set to 'html', this will be sent as the alternative text.timeout
number? Duration in milliseconds to wait before killing the process. If not set, defaults toexports.timeout
global setting.path
string? Optional path to the sendmail executable.
from
Email address from which messages are sent. Used
when from
was not set on a message.
Type: function (email): string
email
string
isValidAddress
Type: function (email): boolean
email
string
timeout
Duration in milliseconds to wait before
killing the process. Defaults to 3000. Used when timeout
is not set
on a message.
Type: function (milliseconds): number
milliseconds
number
Callback
Type: Function
err
Error
SGAppsSessionManagerOptions
Type: object
SGAppsServerRequestSessionCache
Type: object
MountUpdatedURL
Type: string
FaceboxTemplate
Type: function (options)
_debug
Type: boolean
_env
_cachedFiles
INCLUDE_LEVEL
Type: number
render
Type: function (text, vars, env)
renderFile
Type: function (filePath, vars, callback)
renderCode
Type: function (code, vars, callback, virtualFilePath)
SGAppsServerRequestCookie
Type: function ()
get
Type: function (name, options): string
set
Type: function (name, value, options, skipErrors): string
name
stringvalue
stringoptions
object?options.secure
boolean (optional, defaultfalse
)options.secureProxy
boolean?options.signed
boolean?options.path
string (optional, default"/"
)options.expires
Date?options.domain
string?options.httpOnly
boolean (optional, defaulttrue
)options.sameSite
boolean (optional, defaultfalse
)options.secure
boolean (optional, defaultfalse
)options.overwrite
boolean (optional, defaultfalse
)
skipErrors
boolean (optional, defaultfalse
)
SGAppsServerDecoratorsLibrary
Type: function ()
SGAppsServerErrorCallBack
Type: Function
err
Errorrequest
SGAppsServerRequestresponse
SGAppsServerResponseserver
SGAppsServer
SGAppsServerErrorOnlyCallback
Type: Function
err
Error
FSLibrary
Type: function ()
SGAppsServerShared
Type: function ()
SGAppsServerRequestFile
Type: object
SGAppsServerRequestPostDataItem
Type: object
SGAppsServerDecorator
Type: Function
request
SGAppsServerRequestresponse
SGAppsServerResponseserver
SGAppsServercallback
function
SGAppsServer
HTTP Server for high performance results
Type: function (options)
options
object?options.server
Server?options.strictRouting
boolean (optional, defaulttrue
)options.debug
boolean (optional, defaulttrue
)options._DEBUG_MAX_HANDLER_EXECUTION_TIME
object console shows an warn if handler is executed more than ( works in debug mode ) (optional, default500
)options._DEBUG_REQUEST_HANDLERS_STATS
object console shows an warn if handler is executed more than ( works in debug mode ) (optional, defaultfalse
)options._REQUEST_FORM_PARAMS_DEEP_PARSE
boolean parse formData field names to create deep object request.body (optional, defaulttrue
)options.decorators
Array<SGAppsServerDecorator>?
Examples:
// ================================
// Start your ๐ Web-Server app
// ================================
const { SGAppsServer } = require('@sgapps.io/server');
const app = new SGAppsServer();
app.get('/', function (req, res) {
res.send('hello world')
})
app.server().listen(8080, () => {
app.logger.log('Server is running on port 8080');
})
// ========================================
// Start your ๐ Web-Server app Extended
// ========================================
const { SGAppsServer } = require('@sgapps.io/server');
const app = new SGAppsServer();
app.get('/', function (req, res) {
res.send('hello world')
})
app.whenReady.then(() => {
app.SessionManager.cookie = 'ssid';
app.SessionManager.SESSION_LIFE = 120; // seconds
app.server().listen(8080, () => {
app.logger.log('Server is running on port 8080');
})
}, app.logger.error);
CookiesManager
Type: object
COOKIES_KEY
string_enabled
boolean? if is changed to false server will not decorate requests with cookie managerhandle
function (SGAppsServerRequest, SGAppsServerResponse): object
_server
Type: Server
_decorators
Type: Array<SGAppsServerDecorator>
TemplateManager
Type: TemplateManager
_options
Type: SGAppsServerOptions
STATUS_CODES
shared
Type: SGAppsServerShared
logger
Type: LoggerBuilder
Type: function (config): SGAppsServerEmail
config
SGAppsServerEmail.Config
mountPath
Type: string
SessionManager
Type: SGAppsSessionManager
_fs
Type: object
_path
Type: object
EXTENSIONS
Type: ResourcesExtensions
_requestListeners
Type: Object<string, SGAppsServerDictionary>
MAX_POST_SIZE
default value is 16 Kb
ยป 16 * 1024
Type: number
whenReady
Type: Promise<SGAppsServer>
handleRequest
Type: function (request, response, callback)
request
SGAppsServerRequestresponse
SGAppsServerResponsecallback
SGAppsServerDictionaryRunCallBack
handleErrorRequest
Type: function (request, response, err)
request
SGAppsServerRequestresponse
SGAppsServerResponseerr
Error?
handleStaticRequest
Type: function (request, response, path, callback, options)
request
SGAppsServerRequestresponse
SGAppsServerResponsepath
stringcallback
SGAppsServerErrorCallBackoptions
object? (optional, default{timeout:0,autoIndex:[]}
)
handle
Type: function (request, response, callback)
request
IncomingMessageresponse
ServerResponsecallback
SGAppsServerDictionaryRunCallBack?
server
Type: function (): Server
use
Type: function (path, handlers): SGAppsServer
path
(string | RequestHandler)handlers
...RequestHandler?
post
The POST
method is used to submit an entity to the specified resource, often causing a change in state or side effects on the server.
Type: function (path, handlers): SGAppsServer
path
RequestPathStructurehandlers
...RequestHandler
get
The GET
method requests a representation of the specified resource. Requests using GET should only retrieve data.
Type: function (path, handlers): SGAppsServer
path
RequestPathStructurehandlers
...RequestHandler
head
The HEAD
method asks for a response identical to that of a GET request, but without the response body.
Type: function (path, handlers): SGAppsServer
path
RequestPathStructurehandlers
...RequestHandler
put
The PUT
method replaces all current representations of the target resource with the request payload.
Type: function (path, handlers): SGAppsServer
path
RequestPathStructurehandlers
...RequestHandler
trace
The TRACE
method performs a message loop-back test along the path to the target resource.
Type: function (path, handlers): SGAppsServer
path
RequestPathStructurehandlers
...RequestHandler
delete
The DELETE
method deletes the specified resource.
Type: function (path, handlers): SGAppsServer
path
RequestPathStructurehandlers
...RequestHandler
options
The OPTIONS
method is used to describe the communication options for the target resource.
Type: function (path, handlers): SGAppsServer
path
RequestPathStructurehandlers
...RequestHandler
connect
The CONNECT
method establishes a tunnel to the server identified by the target resource.
Type: function (path, handlers): SGAppsServer
path
RequestPathStructurehandlers
...RequestHandler
patch
The PATCH
method is used to apply partial modifications to a resource.
Type: function (path, handlers): SGAppsServer
path
RequestPathStructurehandlers
...RequestHandler
all
add handler to all methods
Type: function (path, handlers): SGAppsServer
path
RequestPathStructurehandlers
...RequestHandler
finalHandler
add final handler to all methods, last added is first
Type: function (path, handlers): SGAppsServer
path
RequestPathStructurehandlers
...RequestHandler
handlePostData
Type: function (options): SGAppsServerHandlerPostData
options
object?
LoggerBuilder
Pretty CLI Logger, with possibility to replace default nodejs' console logger
Type: function ()
Examples:
// =============================
// Use Logger as ๐ป instance
// =============================
const { LoggerBuilder } = require('@sgapps.io/server');
const logger = new LoggerBuilder();
logger.log("Hello world");
// replace default console
const { LoggerBuilder } = require('@sgapps.io/server');
const logger = new LoggerBuilder();
logger.decorateGlobalLogger();
console.log("Console Messages are decorated now");
_format
this parameter may be changed if you decide to change decoration schema
Type: string
Example:
// Insert an message in VT100 format
logger._format = "\x1b[7m {{timestamp}} [{{TYPE}}] <{{title}}> {{file}}:{{line}} ({{method}}){{stack}}\x1b[7m";
_debug
Type: boolean
_headerFormatters
Type: Array<headerFormatter>
prettyCli
Type: function (ref, indent, separator)
log
Type: function (messages)
messages
...any
info
Type: function (messages)
messages
...any
warn
Type: function (messages)
messages
...any
error
Type: function (messages)
messages
...any
prompt
Type: function (callback, message)
callback
LoggerBuilderPromptmessage
(string | Buffer)
Example:
logger.prompt("rerun tests? [y/n]: ", function (err, buffer) {
// trim spaces from response
var response = buffer.toString().replace(/^\s*(.*?)\s*$/, '$1');
if (response === 'y') {
// write your code
}
});
decorateGlobalLogger
Type: function ()
headerFormatterInfo
Type: object
headerFormatter
Type: Function
info
headerFormatterInfo
RequestPathStructureMap
Type: object
key
stringpath
RequestPathStructurehandlers
Array<RequestHandler>
SGAppsServerDictionary
a dictionary for storing
Type: function (options)
options
object?
_paths
Type: Array<RequestPathStructureMap>
_dictionary
Type: Object<string, Array<RequestHandler>>
generatePathKey
Type: function (path): string
path
RequestPathStructure
push
Type: function (path, handlers)
path
RequestPathStructurehandlers
Array<RequestHandler>
Example:
server.get('/', (req, res) => {
res.send('root');
})
// will match "test" "best", everything with est
server.get(/.*est/, (req, res) => {
res.send('root');
})
server.get('/:name/:surname', (req, res) => {
const { name, surname } = req.params;
res.send(`Hi ${name} ${surname}`);
})
// apply rules with regexp emulation, they are marked with "^" in the start
server.get('^/:name([a-z]+)/:age(\d+)', (req, res, next) => {
const { name, age } = req.params;
if (age < 18) {
res.send(`Hi ${name}, you are not allowed`);
} else {
next()
}
})
// apply rules with regexp emulation, they are marked with "^" in the start
server.get('^/([a-z]+)/', (req, res, next) => {
const { name, age } = req.params;
if (age < 18) {
res.send(`Hi ${name}, you are not allowed`);
} else {
next()
}
})
// add regular expression with group names
server.get('^/(?<test>[a-z]+)/', (req, res, next) => {
const { test } = req.params;
res.send(`param: ${test}`);
})
server.get('/', (req, res) => {
res.send('root');
})
run
Type: function (request, response, server, callback)
request
SGAppsServerRequestresponse
SGAppsServerResponseserver
SGAppsServercallback
SGAppsServerDictionaryRunCallBack
RequestPathStructure
RequestHandler
Type: Function
request
SGAppsServerRequestresponse
SGAppsServerResponsenext
function
SGAppsServerOptions
Type: object
server
Server?strictRouting
boolean?_DEBUG_MAX_HANDLER_EXECUTION_TIME
number?_DEBUG_REQUEST_HANDLERS_STATS
boolean?_REQUEST_FORM_PARAMS_DEEP_PARSE
boolean? parse formData field names to create deep object request.body
SGAppsSessionManager
Type: function (server, options)
server
SGAppsServeroptions
SGAppsSessionManagerOptions?
_options
Type: SGAppsSessionManagerOptions
_enabled
Type: boolean
_sessions
Type: Object<string, SGAppsServerRequestSessionCache>
removeExpiredSessions
Type: function ()
handleRequest
Type: function (request)
request
SGAppsServerRequest
RequestSessionDecorator
Type: function (request, response, server, callback)
request
SGAppsServerRequestresponse
SGAppsServerResponseserver
SGAppsServercallback
function
SGAppsServerDictionaryRunCallBack
Type: Function
request
SGAppsServerRequestresponse
SGAppsServerResponseserver
SGAppsServer
request
Type: function (request, response)
request
IncomingMessageresponse
ServerResponse
request
Type: function (request, socket, data)
request
IncomingMessagesocket
Duplexdata
Buffer
LoggerBuilderPrompt
Type: Function
message
Buffer
SGAppsServerHandlerPostData
Type: Function
request
SGAppsServerRequestresponse
SGAppsServerResponsenext
function