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
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 ๐ฆ
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;
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,
waitAllHandlers: true,
path: configuration.database.filesystem.logs + 'default/{year}/{month}/data-{worker-id}.log',
handle: function (data) {
console.info("LOGGER Data", data);
return data.match(/\.txt\"/) ? null : data;
}
};
app.get(/^\/api\//, function () {
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
Type: function (request, options)
Type: number
Type: string
Session was received from previously saved cookie
Type: boolean
Type: string
Type: SGAppsSessionManagerOptions
Type: object
Type: function ()
Type: function (options)
Type: object
Type: TemplateManagerViewer
Type: Object<string, any>
Type: function (templateName): boolean
Type: function (templateName)
Type: function (templateName, filePath)
Type: function (templates)
Type: function (templateName): TemplateManagerTemplate
Type: function (response, templateName, vars)
Type: function (request, server)
Type: IncomingMessage
post data buffer cache
Type: Buffer
Type: function (url): MountUpdatedURL
Type: object
Type: object
Type: string
Type: object
Type: Array<SGAppsServerRequestPostDataItem>
Type: SGAppsServerRequestCookie
Type: number
Examples:
request.MAX_POST_SIZE = 4 * 1024 * 1024;
request.MAX_POST_SIZE = -1;
Type: Object<string, Array<SGAppsServerRequestFile>>
Type: Array<SGAppsServerRequestFile>
Array of functions to be called on response end
Type: Array<function>
Array of functions to be called on response end
Type: SGAppsServerRequest.RequestParams
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
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
object
fieldName
string
fieldData
any
options
object?
options.transform2ArrayOnDuplicate
boolean (optional, default false
)
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);
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);
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
}
}
Type: SGAppsServerRequestSession
request's post received data
Type: Promise<Buffer>
Type: (Object<(string | number), string> | Array<string>)
Type: function (route, url, strictRouting, _cache)
Type: function (response, server)
Type: ServerResponse
Type: function (filePath, callback)
Type: function (data, options)
Type: function (error, options)
Array of functions to be called on response end
Type: Array<function>
if it returns false
than the action was not possible
Type: function (url, options)
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).
Type: Function
Type: function (filePath, fileName, callback, options)
filePath
string
fileName
string
callback
SGAppsServerResponse.pipeFileStaticCallback
options
object?
options.timeout
number (optional, default 0
)
options.filePath
string? originap path is autoIndex was applied
options.autoIndex
Array<string>? list of auto-index files, ex: ['index.html', 'index.htm', 'default.html']
Type: function (statusCode)
Type: object
Type: function (options)
Type: FaceboxTemplate
Type: boolean
Type: Object<string, any>
Type: function (code, vars, virtualFilePath, callback)
Type: function (response, view, vars)
Type: object
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 email
Type: function (callback)
callback
SGAppsServerEmail.Callback
get message options
Type: object
getter generate encoded body
Type: string
getter generate all email structure
Type: string
check if email is valid
Type: function (callback)
callback
SGAppsServerEmail.Callback
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 sent
debug
boolean?
from
string? Email address from which this msg is sent. If not set defaults to the exports.from
global setting.
replyTo
string? Email address to which replies will be sent. If not
set defaults to from
cc
(string | Array<string>)? Email address(es) who receive a copy
bcc
(string | Array<string>)? Email address(es) who receive a blind copy
subject
string The subject of the email
body
string The message of the email
bodyType
string? Content type of body. Only valid option is
'html' (for now). Defaults to text/plain.
altText
string? If bodyType
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 to exports.timeout
global setting.
path
string? Optional path to the sendmail executable.
Email address from which messages are sent. Used
when from
was not set on a message.
Type: function (email): string
Type: function (email): boolean
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
Type: Function
Type: object
Type: object
Type: string
Type: function (options)
Type: boolean
Type: Object<string, any>
Type: Object<string, string>
Type: number
Type: function (text, vars, env)
Type: function (filePath, vars, callback)
Type: function (code, vars, callback, virtualFilePath)
Type: function ()
Type: function (name, options): string
Type: function (name, value, options, skipErrors): string
name
string
value
string
options
object?
options.secure
boolean (optional, default false
)
options.secureProxy
boolean?
options.signed
boolean?
options.path
string (optional, default "/"
)
options.expires
Date?
options.domain
string?
options.httpOnly
boolean (optional, default true
)
options.sameSite
boolean (optional, default false
)
options.secure
boolean (optional, default false
)
options.overwrite
boolean (optional, default false
)
skipErrors
boolean (optional, default false
)
Type: function ()
Type: Function
Type: Function
Type: function ()
Type: function ()
Type: object
fieldName
string field's name
data
object
data.fileName
string file's name [duplicate]
data.encoding
string file's encoding
data.fileStream
Readable () => fileStream
data.fileData
Buffer
data.fileSize
number size in bytes
data.contentType
string file's mimeType
data.loaded
boolean indicate if file is fully loaded into fileData
Type: object
Type: Function
HTTP Server for high performance results
Type: function (options)
options
object?
options.server
Server?
options.strictRouting
boolean (optional, default true
)
options.debug
boolean (optional, default true
)
options._DEBUG_MAX_HANDLER_EXECUTION_TIME
object console shows an warn if handler is executed more than ( works in debug mode ) (optional, default 500
)
options._DEBUG_REQUEST_HANDLERS_STATS
object console shows an warn if handler is executed more than ( works in debug mode ) (optional, default false
)
options._REQUEST_FORM_PARAMS_DEEP_PARSE
boolean parse formData field names to create deep object request.body (optional, default true
)
options.decorators
Array<SGAppsServerDecorator>?
Examples:
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');
})
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;
app.server().listen(8080, () => {
app.logger.log('Server is running on port 8080');
})
}, app.logger.error);
Type: object
COOKIES_KEY
string
_enabled
boolean? if is changed to false server will not decorate requests with cookie manager
handle
function (SGAppsServerRequest, SGAppsServerResponse): object
Type: Server
Type: Array<SGAppsServerDecorator>
Type: TemplateManager
Type: SGAppsServerOptions
Type: Object<number, string>
Type: SGAppsServerShared
Type: LoggerBuilder
Type: function (config): SGAppsServerEmail
config
SGAppsServerEmail.Config
Type: string
Type: SGAppsSessionManager
Type: object
Type: object
Type: ResourcesExtensions
Type: Object<string, SGAppsServerDictionary>
default value is 16 Kb
ยป 16 * 1024
Type: number
Type: Promise<SGAppsServer>
Type: function (request, response, callback)
Type: function (request, response, err)
Type: function (request, response, path, callback, options)
Type: function (request, response, callback)
Type: function (): Server
Type: function (path, handlers): SGAppsServer
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
The GET
method requests a representation of the specified resource. Requests using GET should only retrieve data.
Type: function (path, handlers): SGAppsServer
The HEAD
method asks for a response identical to that of a GET request, but without the response body.
Type: function (path, handlers): SGAppsServer
The PUT
method replaces all current representations of the target resource with the request payload.
Type: function (path, handlers): SGAppsServer
The TRACE
method performs a message loop-back test along the path to the target resource.
Type: function (path, handlers): SGAppsServer
The DELETE
method deletes the specified resource.
Type: function (path, handlers): SGAppsServer
The OPTIONS
method is used to describe the communication options for the target resource.
Type: function (path, handlers): SGAppsServer
The CONNECT
method establishes a tunnel to the server identified by the target resource.
Type: function (path, handlers): SGAppsServer
The PATCH
method is used to apply partial modifications to a resource.
Type: function (path, handlers): SGAppsServer
add handler to all methods
Type: function (path, handlers): SGAppsServer
add final handler to all methods, last added is first
Type: function (path, handlers): SGAppsServer
Type: function (options): SGAppsServerHandlerPostData
Pretty CLI Logger, with possibility to replace default nodejs' console logger
Type: function ()
Examples:
const { LoggerBuilder } = require('@sgapps.io/server');
const logger = new LoggerBuilder();
logger.log("Hello world");
const { LoggerBuilder } = require('@sgapps.io/server');
const logger = new LoggerBuilder();
logger.decorateGlobalLogger();
console.log("Console Messages are decorated now");
this parameter may be changed if you decide to change decoration schema
Type: string
Example:
logger._format = "\x1b[7m {{timestamp}} [{{TYPE}}] <{{title}}> {{file}}:{{line}} ({{method}}){{stack}}\x1b[7m";
Type: boolean
Type: Array<headerFormatter>
Type: function (ref, indent, separator)
ref
any
indent
number?
separator
string (optional, default " "
)
Type: function (messages)
Type: function (messages)
Type: function (messages)
Type: function (messages)
Type: function (callback, message)
Example:
logger.prompt("rerun tests? [y/n]: ", function (err, buffer) {
var response = buffer.toString().replace(/^\s*(.*?)\s*$/, '$1');
if (response === 'y') {
}
});
Type: function ()
Type: object
Type: Function
Type: object
a dictionary for storing
Type: function (options)
options
object?
options.name
string (optional, default ""
)
options.reverse
boolean (optional, default false
)
Type: Array<RequestPathStructureMap>
Type: Object<string, Array<RequestHandler>>
Type: function (path): string
Type: function (path, handlers)
Example:
server.get('/', (req, res) => {
res.send('root');
})
server.get(/.*est/, (req, res) => {
res.send('root');
})
server.get('/:name/:surname', (req, res) => {
const { name, surname } = req.params;
res.send(`Hi ${name} ${surname}`);
})
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()
}
})
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()
}
})
server.get('^/(?<test>[a-z]+)/', (req, res, next) => {
const { test } = req.params;
res.send(`param: ${test}`);
})
server.get('/', (req, res) => {
res.send('root');
})
Type: function (request, response, server, callback)
Type: (string | RegExp)
Type: Function
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
Type: function (server, options)
Type: SGAppsSessionManagerOptions
Type: boolean
Type: Object<string, SGAppsServerRequestSessionCache>
Type: function ()
Type: function (request)
Type: function (request, response, server, callback)
Type: Function
Type: function (request, response)
request
IncomingMessage
response
ServerResponse
Type: function (request, socket, data)
request
IncomingMessage
socket
Duplex
data
Buffer
Type: Function
Type: Function