Simple implementation of a Node Express server described using a Swagger API, in JSON form.
Just do something like
npm install --save swagger-boilerplate
as usual to install. Then to use:
var SwaggerServer = require('swagger-boilerplate').Server;
var swaggerServer =
new SwaggerServer({
apiDef: './apiDef.yml',
modulePath: __dirname + '/',
appName: 'Test Swagger Module Implementation',
serverPort: 8124,
allowedCorsOrigins: 'http://sample.com,https://example.com']
});
swaggerServer.start();
The module exports the following objects:
SwaggerServer constructs (and returns) an Express App based on a YML file. The way the Express App is constructed is described below.
new SwaggerServer(options);
Options can have the following attributes:
-
apiDef: Path of a YML file that holds the API definition for the server. See the testboilerplate/apiDef.yml file for an example. The API definition is a standard YML API definition, extended with the following keywords:
- x-implementation-module: String. Module that holds the implementation of all the defined methods. It must be a string resolvable by require(), so either a local path or a module name. All the rest of the methods defined in the file must be exposed in this module. This keyword must appear at top level.
- x-implementation-middleware: Array. List of methods that will be invoked as a middleware for all the paths defined in the file. The methods will be invoked before the path specific method, and they will be called in the order defined. Methods must conform with the express middleware definition.
- x-implementation-configuration: Method that will be called once before starting the app, to allow any pre-configuration needed. It must return a promise, that will fulfill when the method has finished whatever process it needs to do. The value of the promise must/should be any configuration values that you might want to use on other parts. See below.
- x-multipart-options: This module uses multer to process mutipart/form-data parameters
(files). This parameter defines a function that will be called to set the multer options for
your applications. The function receives two parameters:
- config: The fulfillment value of the method you declared to configure your server.
- multer: The multer object that will be used to process the files.
- x-static-paths: This must be a function that will receive the fulfillment value of the
configuration promise, and must return an array of objects with the following attributes:
- url: URL that the static path will be served on
- path: local path of the directory that will be served on that URL.
- x-implemented-in: For any given exposed API, the method that implements it. Must conform to the express method definition. If the key is used on a Security Definition, it's the module (also as a express Middleware) that implements the authentication. It's up to the module implementator to decide how to pass the authentication results to the actual methods.
- x-implementation-final-middleware: Array of last middleware on the chain (usually error handlers). This will be executed after the specific path method, only if the specific call method explicitly invoked the next method in the chain.
-
modulePath: Path where the x-implementation-module module will be loaded from.
-
appName: Name of the Main Module of the application (for the logs)
-
serverPort: Port where the server must start by default (if not overriden by a command line parameter or by the SERVER_PORT environment variable.
-
allowedCorsOrigins: Array of domains that will be added to the origin white list for CORS marked APIs. Note that if this parameter is not present, '*' will be used instead!
This constructor also parses the command line. It accepts the following parameters:
-
-h, --help Displays this help.
-
-d, --daemon Starts as a daemon.
-
-l, --logFile=ARG Logs output to this file, only if started as a daemon.
-
-L, --logLevel=ARG Desired log level, expressed as a string such as "warn,error". The possible values are (from more detail to less):
- trace
- log
- warn
- error
by default the value is "error,warn,log".
-
-p, --serverPort=ARG Server listening port. If not present it uses either the PORT env variable or the 8123 port
-
-u, --user=ARG UID (name or number) to fork to after binding the port. This only works on Unix-like systems, where process.getuid is implemented.
-
-s, --staticPath=ARG Directory that holds the static files. By default it's the ./web directory.
-
-C, --certDir=ARG Directory that holds the cert.pem and key.pem files. Only used if -S is specified also.
-
-S, --secure Starts as a secure server (HTTPS). Requires -C also to find the certificates.
- start: Starts the server, listening on the port that is:
- The SERVER_PORT environment variable or if that's not set
- The parameter passed as -p on the command line or if that's not set
- The serverPort attribute passed on the constructor, or if that's not set
- The port 8123.
The app also exposes the Util file as /shared/js/Utils.js in case you want to use it.
Also, if you tag some API with CORS, then it will be CORS promiscuous (at this moment, its an all or nothing sorry)
Simple logger that allow multiple level logs. The configured level must be a bitmask of the desired enabled levels.
Usage:
var logger = new MultiLevelLogger('Logger Name', 4); // Enable only error
logger.error('Test error'); // Logs an error
logger.log('Test log'); // does nothing
logger.enableLevel(1); // enable the log level
logger.log('Test log'); Prints the log
logger.disableLevel(1); Disable the log level (but leaves the rest)
Default defined levels:
- error: 1
- warn: 2
- log: 4
- trace: 8
new MultiLevelLogger(name, initialLogLevel);
- name: Name of this logger. It will be printed on all the log lines.
- initialLogLevel: Initial value for the enabled log levels.
- enableLevel(aLevel): Enables the passed levels (while keeping any other enabled values set).
- disableLevel(aLevel): Disables the passed levels (while keeping any other enabled values set)
- logLevel (attribute): Used to set or read the current log level.
- log(arguments): Logs the passed arguments, if the 'log' level is enabled.
- error(arguments): Logs the passed arguments, if the 'error' level is enabled.
- trace(arguments): Logs the passed arguments, if the 'trace' level is enabled.
- warn(arguments): Logs the passed arguments, if the 'warn' level is enabled.
var fs = require('fs');
var readFile = Utils.promisify(fs.readFile);
readFile('something').then(r => doWhatever);
If callbackFn is a typical node callback function (of the kind that returns the error as the first argument, and the value(s) as the second and subsequent arguments, this method returns a new function that returns a promise that will fullfill if callbackFn would have succeeded.
- *callbackFn: the original function
- numRetValues: The number of values that the original function would return. By default, 1.
- fnThis: If set, the returned function is bound to the fnThis value. By default, it's undefined. Needed when promisifying methods that use this.
Returns a new object (of the first argument class) if the same object hasn't been constructed already, or a cached object if it's been cached already. Note that this implementation requires WeakMap, so it won't work on IE9.
If at some point this is needed on IE it will have to be implemented using x-linked arrays.
var aObject = new Utils.CachifiedObject(Date, dateString);
// aObject will be the same as:
// aObject = new Date('dateString'); but if aObject was built already, a reference will be returned instead
- aBaseObject: Name of the type/constructor of the base object.
- arguments: List (not an array) of parameters that the original constructor gets.
It will return a new instance if:
- There wasn't an old instance already for that type or
- The number of arguments has changed or
- The actual arguments have changed
Otherwise it returns a reference to the previously created instance. Note that it also replaces the previous instance on the cache (so it loses that reference).
- CachifiedObject.getCached(ObjectType): Returns the cached value of the requested type if it exists.
const TEMPLATE = {
a1: '',
a2: 3
};
Utils.isA(TEMPLATE, {}); // false
Utils.isA(TEMPLATE, {a1: 'foo', a2: 'bar'}); // false
Utils.isA(TEMPLATE, {a1: 'foo', a2: 45}); // true
Returns true if the object is of the same type than the template. That is, is a kind of "is object a template". The function will return true when, for attributes that are arrays on the template, all the elements of the array in object are of the same type (isA) than the first element of the array on the template
Utils.booleanify('true'); // true
Utils.booleanify('something'); // false
Returns true value looks like true. Or in this case, 'true', 'TRUE', any number different from 0, and of course true
var a = {
a1: 1,
a2: 2,
a3: 3
};
var b = {
a1: 'foo',
a4: 'bar'
}
Utils.extendCopy(a, b); // Returns {a1: 'foo', a2: 2, a3: 3, a4: 'bar'}
Copies from aExtraElems into aSrc. Returns a new object.
WIP WIP WIP
This module implements all the persistence management that the server has to keep. It can be initialized with an object that specifies a set of keys (with default values) that have to be cached. Usually that can be used to retrieve the server configuration.
The object created will be a promise instance that will be resolved when the requested initial set of data is available. The fulfilled value of the promise will hold both the requested cached data and the methods needed to process the rest of the persistent data.
new ServerPersistence(aCachedEntries, aConnectParameters, aLogLevel, aModules, aPrefix);
The object will use whatever is defined in aModules. PersistenceProvider (or ioredis by default) to store the persistent information.
The PersistenceProvider must implement a subset of the ioredis interface. Specifically:
- Constructor
- It should emit the 'ready' event (set with provider.on('ready', callback)
- get(aKey) => Promise
- set(aKey) => Promise
- pipeline()
- pipepine.get
- pipeline.exec