New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

@comodinx/microservice

Package Overview
Dependencies
Maintainers
1
Versions
37
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@comodinx/microservice

@comodinx/microservice is a Node.js microservice base helpers.

latest
Source
npmnpm
Version
0.1.2
Version published
Maintainers
1
Created
Source

@comodinx/microservice

Node.js microservice base helpers.

Index

  • Download & Install
  • How is it used?
  • Tests

Download & Install

NPM

npm i @comodinx/microservice

Source code

git clone https://gitlab.com/comodinx/microservice.git
cd microservice
npm i

How is it used?

NOTE: Based on bluebird promises.

Getting started

const pkg = require('./package.json');
const { app, listen } = require('@comodinx/microservice/server');
const { errors, health } = require('@comodinx/microservice/server/routes');

app.get('/', (req, res) => res.send('Hello World!'));

// Handle route for health check
health(app, { pkg /* , router, database, services: ['other-service-name'] */ });

// Handle all errors (400, 404, 500, etc...)
errors(app);

listen(app);
/*
 * Listen routes
 *  + GET  /        Home
 *  + GET  /health  Health check
 *  + ANY  /*       404 error. {code: 404, error: 'Not Found'}
 */

Configure

For app/server.

Environment variableValuesTypeDefault valueDescription
SERVER_HOSThost namestringundefinedHost name where the server listens
SERVER_PORT / PORTport numbernumber8000Port where the server listens
SERVER_MULTIPARTtrue/falsebooleanfalseIndicate if app use support for multipart middleware
SERVER_HEALTH_PATHhealth check pathstring"/health"Route for health check endpoint
BODY_PARSER_LIMITrequest limitstring"5mb"Indicate request size limit (generic, apply to raw, text, json and urlencoded)
BODY_PARSER_RAW_LIMITrequest limit for rawstring"5mb"Indicate request size limit for raw
BODY_PARSER_TEXT_LIMITrequest limit for textstring"5mb"Indicate request size limit for text
BODY_PARSER_JSON_LIMITrequest limit for jsonstring"5mb"Indicate request size limit for json
BODY_PARSER_URLENCODED_LIMITrequest limit for url encodedstring"5mb"Indicate request size limit for url encoded

(go to top)

For database

Simple configuration
Environment variableValuesTypeDefault valueDescription
DB_ENABLEDtrue/falsebooleantrueIndicate if need support for database
DB_NAMEdatabase namestringnull
DB_HOSTdatabase host namestring'localhost'
DB_PORTdatabase portnumber3306
DB_USERdatabase userstring'username'
DB_PASSdatabase passwordstringnull
DB_TIMEZONEdatabase timezonestring'+00:00'

(go to top)

Read/Write replication configuration
Environment variableValuesTypeDefault valueDescription
DB_HOST_WRITEdatabase host namestringDB_HOSTDatabase host name for write replication
DB_PORT_WRITEdatabase portnumberDB_PORTDatabase port for write replication
DB_USER_WRITEdatabase userstringDB_USERDatabase username for write replication
DB_PASS_WRITEdatabase passwordstringDB_PORTDatabase password for write replication
DB_HOST_READdatabase host namestringDB_HOSTDatabase host name for read replication
DB_PORT_READdatabase portnumberDB_PORTDatabase port for read replication
DB_USER_READdatabase userstringDB_USERDatabase username for read replication
DB_PASS_READdatabase passwordstringDB_PORTDatabase password for read replication

(go to top)

Pool configuration
Environment variableValuesTypeDefault valueDescription
DB_POOL_ENABLEDtrue/falsebooleantrueIndicate if need support for db pool connections
DB_POOL_MAXmax pool connectionsnumber10Maximum number of connection in pool
DB_POOL_MINmin pool connectionsnumber0Minimum number of connection in pool
DB_POOL_IDLEmax idle timenumber10000Maximum time, in milliseconds, that a connection can be idle before being released
DB_POOL_ACQUIREmax time reconnectnumber60000Maximum time, in milliseconds, that pool will try to get connection before throwing error
DB_POOL_EVICTinterval timenumber1000Time interval, in milliseconds, after which sequelize-pool will remove idle connections

(go to top)

For services

Environment variableValuesTypeDefault valueDescription
SERVICE_AGENTservice agent namestring''
SERVICE_CONNECTION_TIMEOUTnumber in milisecondsnumber21000
SERVICE_REQUEST_TIMEOUTnumber in milisecondsnumber20000

(go to top)

For global dependencies

Environment variableValuesTypeDefault valueDescription
DEFAULT_LOCALElocalestring'es'Default locale
MOMENT_LOCALElocalestringDEFAULT_LOCALEDefault locale for moment module
MOMENT_DEFAULT_FORMATdate formatstring'YYYY-MM-DD HH:mm:ss'Default format for moment.format
NUMERAL_LOCALElocalestringDEFAULT_LOCALEDefault locale for numeral module
NUMERAL_DEFAULT_INTEGER_FORMATnumber formatstring'0,0'Example usage numeral(1000).format(numeral.defaultIntegerFormat)
NUMERAL_DEFAULT_DECIMAL_FORMATnumber formatstring'0,0.00'Example usage numeral(10.01).format(numeral.defaultDecimalFormat)
NUMERAL_DEFAULT_BALANCE_FORMATnumber formatstring'$ 0,0.00'Example usage numeral(100.2).format(numeral.defaultBalanceFormat)
LODASH_TRUNCATE_LENGTHlengthnumber24Default truncate length use for lodash. Example usage _.truncate('hi-diddly-ho there');
LODASH_TRUNCATE_SEPARATORstring separatorstring' 'Default truncate separatotr use for lodash. Example usage _.truncate('hi diddly there');

(go to top)

Detailed explanation

Server

const {
    // Base express application instance
    //  Example usage:
    //   app.get('/', (req, res) => res.send('Hello World!'));
    app,

    // Listen express application instance.
    // If the `config('server.https.enabled')` is false, listen from the express application instance will be executed.
    // If the `config('server.https.enabled')` is true, listen from the instance of https.createServer({ key, cert }) will be executed.
    //  Example usage:
    //   listen(app);
    //
    // NOTE: Listen does nothing when NODE_ENV=test
    listen
} = require('@comodinx/microservice/server');

(go to top)

Routes

const {
    // Routes for error handling. Handle all responses errors (400, 404, 500, etc...)
    errors,

    // Route for health check.
    health
} = require('@comodinx/microservice/server/routes');
Examples for errors

Simple usage

errors(app);
Examples for health

Simple usage

health(app);

Complex usage

health(/* express appplication or express.Router */ app, {

  // To be able to change the url of health check.
  url: '/health',

  // To be able to import package.json and tag.json if they exist. <process.cwd()>
  rootDir: null,

  // For add package information details on health response. (name, description and version) <require('./package.json')>
  pkg: null,

  // For add tag details on health response. <{commit, version, name}>
  tag: null,

  // IDEM url. Default `url`
  path: null,

  // In order to run the health check on a specific router (express.Router).
  router: null,

  // For add database information details on health response. (is alive, error). <database instance require('@comodinx/sequelize')>
  database: null,

  // For add required services information details on health response. (is alive, error) <string list of services added to @comodinx/microservice/helpers/service>
  service: null
});

(go to top)

Get by ID

Get model by id

const Route = require('@comodinx/microservice/server/routes/getById');

const route = new Route('YourModel', {
    // Indicates the name of the parameter to search in `req.params`. Default 'id'
    paramNameId: 'id',

    // Indicates the validation that will be applied to the parameter. Default 'isInteger'
    // Possible values:
    //  Function
    //    Example:
    //      function (id, req) { return id > 10; }
    //  String (https://www.gitlab.com/comodinx/microservice#validator)
    validatorIdType: 'isInteger'
});

module.exports = route.handlerize();

(go to top)

Destroy

Delete model. (**WARNING** - Physical erasure! If req.query.force = true)

const Route = require('@comodinx/microservice/server/routes/destroy');

const route = new Route('YourModel', {
    // Indicates the name of the parameter to search in `req.params`. Default 'id'
    paramNameId: 'id',

    // Indicates the validation that will be applied to the parameter. Default 'isInteger'
    // Possible values:
    //  Function
    //    Example:
    //      function (id, req) { return id > 10; }
    //  String (https://www.gitlab.com/comodinx/microservice#validator)
    validatorIdType: 'isInteger'
});

module.exports = route.handlerize();

(go to top)

List

DEPRECATED List (pagination, filter, order and group) from database model

const Route = require('@comodinx/microservice/server/routes/list');

const route = new Route('YourModel', {
    // Indicates the page size. Default 10
    defaultPageSize: 10,

    // Indicates the validation that will be applied to the parameter. Default null
    // Possible values:
    //  Object with key-value, where the key is the name of the parameter in the filter, and the value is the name of the column in the database
    //    Example:
    //      { idType: 'id_yourmodel_type' }
    mapKeyParse: null
});

module.exports = route.handlerize();

(go to top)

List by query

List (pagination, filter, order and group) from database model

const Route = require('@comodinx/microservice/server/routes/listByQuery');

const route = new Route('User', {
    // Relationship with others tables or services. Default value is null
    relationships: [
        // Example for related table
        {
            // relationship name
            name: 'attributes',
            // related table name
            table: 'job_candidates',
            // field needed from related table for join relationship
            fieldSource: 'candidates.id_job',
            // field needed from model for match join relationship
            fieldTarget: 'jobs.id'
        },

        // Example for related with remote service
        {
            // relationship name
            name: 'person',
            // indicate that relationship is with a remote service
            remote: 'true',
            // service name. helpers/service[<service name>]
            service: 'people',
            // url of remote endpoint
            uri: '/people',
            // field needed from remote service for join relationship
            fieldSource: 'id',
            // field needed from model for match join relationship
            fieldTarget: 'users.id_person'
        }
    ],

    // Indicates the page size. Default 10
    defaultPageSize: 10,

    // Indicates the validation that will be applied to the parameter. Default null
    // Possible values:
    //  Object with key-value, where the key is the name of the parameter in the filter, and the value is the name of the column in the database
    //    Example:
    //      { idType: 'id_yourmodel_type' }
    mapKeyParse: null
});

module.exports = route.handlerize();

(go to top)

Proxy

Handrails between microservices

const Route = require('@comodinx/microservice/server/routes/proxy');

const route = new Route({
    // Indicates the service name defined on @comodinx/microservice/helpers/service.
    serviceName: 'myService',

    // Indicates the function use on service instance. Default `req.method`
    serviceMethod: req.method,

    // Indicates the path use when calling service. Default `req.path`
    serviceUrl: req.path,

    // Extra service request options. Default `{}`
    serviceOptions: {
      responseType: 'json'
    },

    // Indicate if response with the same service response content type.
    sameContentType: true

    // TODO :: Send in service request, the same header from original request
    // headers: [
    //   'authorization'
    // ]
});

module.exports = route.handlerize();
Base route
const _ = require('lodash');
const Base = require('@comodinx/microservice/server/routes');
const { validator } = require('@comodinx/microservice/helpers');
const { errors, database } = require('@comodinx/microservice');
// ...
class Route extends Base {
    /**
     * Validate request
     */
    validate (req) {
        if (_.isEmpty(req.params)) {
            throw new errors.BadRequest('Bad request. Please set "id" parameter');
        }
        if (!validator.isInteger(req.params.id)) {
            throw new errors.BadRequest('Bad request. Please use "id" on parameters');
        }
        return req;
    }

    /**
     * Handle request
     */
    handler (req) {
        return database.models.YourModel.getById(req.params.id).then(model => {
            if (!model) {
                throw new errors.NotFound(`Not found model ${context.id}`);
            }
            return model;
        });
    }
}

module.exports = (new Route()).handlerize();

(go to top)

Config

In order to see all config documentation click here

const { config } = require('@comodinx/microservice');
// ...
// Read configuration
config('server.port'); // 8000

// Extend current configuration.
config.extend({ server: { port: 8001 } });
config('server.port'); // 8001

// Use default value.
config('server.port2', 8001); // 8001

(go to top)

Database

In order to see all database documentation click here

database instance
const { errors, database } = require('@comodinx/microservice');
// ...
return database.models.YourModel.getById(id).then(yourModel => {
    if (!yourModel) {
        throw new errors.NotFound(`Model not found ${id}`);
    }
    return yourModel;
});

Example use raw database, function query

In order to see all operators click here

const { database } = require('@comodinx/microservice');
// ...
return database.models.YourModel.find({
    where: {
        deleted_at: {
            [database.Op.is]: null
        }
    },
    order: [['id', 'DESC']],
    limit: 100,
    offset: 0
});

Example use raw database, function query

In order to see all query types click here

const { database } = require('@comodinx/microservice');
// ...
return database.query('UPDATE users SET active = 0 WHERE id = 1', { type: database.QueryTypes.UPDATE }).spread((results, metadata) => {
    // ...
    return metadata;
});
database model

Bear in mind that everything has an order. Extending the models (for now) requires an order in the require

In the first file of our app / microservice, we have to do the require in the following order

// Setting
require('./config');

// Dependencies
require('@comodinx/microservice/helpers/dependencies');

// Our model extensions
require('./models');

...
Example add extra functionality on model.

File path models/organizations.js

File source:

const { database, database: { Model } } = require('@comodinx/microservice');

class Organizations extends Model {
    /*
     * Function used for populate relationships when model if loaded.
     */
    populate (organization, options) {
        options = options || {};

        if ((options.tiny && !options.with) || options.small) {
            return super.populate(organization, options);
        }

        return super.populate(organization, options)
            // Load users, from remote users service, related with the organization.
            .then(() => this.populateRemotes(organization, 'users', options));
    }

    /*
     * Another extra function
     */
    findAllActives () {
        // ...
    }
}

// Export model Organizations, and extend model organizations on database instance.
module.exports = database.models.Organizations = Organizations;

Usage model extension:

const { database } = require('@comodinx/microservice');

database.models.Organizations.findAllActives().then(models => ...);

(go to top)

Errors

const { errors } = require('@comodinx/microservice');
// ...
throw new errors.NotFound();
// All HTTP Status Code are an Exception
const e = new errors.NotFound('My custom message', {hello: 'world'});
// ...
console.log(e.toJson());
// { "error": 'My custom message', "code": 404, "extra": { "hello": "world" } }

(go to top)

Validator

In order to see all validation functions click here

const validator = require('@comodinx/microservice/helpers/validator');

validator.isEmail('johndoe@gmail.com'); // true
Custom validations.
Integer
validator.isInteger(); // false
validator.isInteger(null); // false
validator.isInteger('a'); // false
validator.isInteger('6'); // true
validator.isInteger('6.1'); // false
validator.isInteger('-6'); // true
validator.isInteger(6); // true
validator.isInteger(6.1); // false
validator.isInteger(-6); // true
Number
validator.isNumber(); // false
validator.isNumber(null); // false
validator.isNumber('a'); // false
validator.isNumber('6'); // true
validator.isNumber('6.1'); // true
validator.isNumber('-6'); // true
validator.isNumber(6); // true
validator.isNumber(6.1); // true
validator.isNumber(-6); // true

(go to top)

Logger

const logger = require('@comodinx/microservice/helpers/logger');

logger.error(new Error('Not Found')); // [2020-01-28T17:16:50.379Z] - ERROR - ✘ Ooops... Error: Not Found
logger.error('This is an error');     // [2020-01-28T17:16:50.379Z] - ERROR - ✘ Ooops... This is an error
logger.warn('This is a warning');     // [2020-01-28T17:16:50.381Z] - WARN - ⚠ This is a warning
logger.info('Hello World!');          // [2020-01-28T17:16:50.381Z] - INFO - Hello World!
logger.title('Hello World!');         // [2020-01-28T17:16:50.382Z] - INFO - ==========   Hello World!   ==========
logger.success('Hello World!');       // [2020-01-28T17:16:50.383Z] - INFO - ✔ Hello World!
logger.arrow('Hello World!');         // [2020-01-28T17:16:50.384Z] - INFO - • Hello World!
logger.step('Hello World!');          // [2020-01-28T17:16:50.384Z] - INFO - ✦ Hello World!
logger.lap('Hello World!');           // [2020-01-28T17:16:50.384Z] - INFO - ➜ Hello World!

(go to top)

Tests

In order to see more concrete examples, I INVITE YOU TO LOOK AT THE TESTS :)

Run the unit tests

npm test

(go to top)

FAQs

Package last updated on 08 Mar 2022

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts