README
core express based node js library
Core library to built an express based service in node js.
Built With
Libraries
- Exposed Libraries
- auth
- Server
- Router (express.Router)
- utils
- connectSequelizeDb
- validate
- errors
Descriptions
auth
Authentication library using jwt. consists of :
- verifyToken : to verify access token using JWT-RS256 encryptions
- authenticateRequest : to authenticate any incoming requests with token and schema
- sign : to sign in any data with the private token
- hash : hash any text using sha256 hashing
- decode : to decode any token given using jwt-decode
Server
Main express server class to be instantiated
- verifyToken : to verify access token using JWT-RS256 encryptions
- authenticateRequest : to authenticate any incoming requests with token and schema
- sign : to sign in any data with the private token
- hash : hash any text using sha256 hashing
- decode : to decode any token given using jwt-decode
Router
Authentication library using jwt. consists of :
- verifyToken : to verify access token using JWT-RS256 encryptions
- authenticateRequest : to authenticate any incoming requests with token and schema
- sign : to sign in any data with the private token
- hash : hash any text using sha256 hashing
- decode : to decode any token given using jwt-decode
utils
Authentication library using jwt. consists of :
- verifyToken : to verify access token using JWT-RS256 encryptions
- authenticateRequest : to authenticate any incoming requests with token and schema
- sign : to sign in any data with the private token
- hash : hash any text using sha256 hashing
- decode : to decode any token given using jwt-decode
connectSequelizeDb
Authentication library using jwt. consists of :
- verifyToken : to verify access token using JWT-RS256 encryptions
- authenticateRequest : to authenticate any incoming requests with token and schema
- sign : to sign in any data with the private token
- hash : hash any text using sha256 hashing
- decode : to decode any token given using jwt-decode
validate
Authentication library using jwt. consists of :
- verifyToken : to verify access token using JWT-RS256 encryptions
- authenticateRequest : to authenticate any incoming requests with token and schema
- sign : to sign in any data with the private token
- hash : hash any text using sha256 hashing
- decode : to decode any token given using jwt-decode
errors
Authentication library using jwt. consists of :
- verifyToken : to verify access token using JWT-RS256 encryptions
- authenticateRequest : to authenticate any incoming requests with token and schema
- sign : to sign in any data with the private token
- hash : hash any text using sha256 hashing
- decode : to decode any token given using jwt-decode
Getting Started
Prerequisites
- Node.js v^8.10.0
- npm v^6.4.1
Installing
- clone repository : npm install @bage/core-express
- instantiate
- modify .env configurations into api used values
- Run npm install : npm install
Running service
npm run start
Orchestrating Server
const Producer = require('sqs-producer');
const Sequelize = require('sequelize');
const { Server, connectSequelizeDb } = require('../core');
const config = require('../config');
const { CityDb, CustomerDb, SQSApi } = require('./repositories');
const { City, Hello } = require('./services');
const routes = require('./routes');
/**
* Initiating DB connections and instantiate DB classes (CityDb, CustomerDb)
* @param {object} app - express server object
*/
const initDB = (app) => {
const { logger } = app.locals;
const dbConfig = config.resources.db;
app.locals.Sequelize = Sequelize;
const crowdSysDb = connectSequelizeDb(Sequelize, dbConfig, logger);
const opts = {
logger, crowdSysDb, Sequelize
};
app.locals.cityDb = new CityDb(opts);
app.locals.customerDb = new CustomerDb(opts);
};
/**
* Initiating other api connections and instantiate API access classes (SQSApi)
* @param {object} app - express server object
*/
const initApi = (app) => {
const { url, region, accessKey, secretKey } = config.resources.sqs;
const producer = Producer.create({
queueUrl: url,
region: region,
accessKeyId: accessKey,
secretAccessKey: secretKey
});
const { logger } = app.locals;
const opts = {
logger,
producer
};
app.locals.sqsApi = new SQSApi(opts);
};
/**
* Initiating api service classes (City, Hello)
* @param {object} app - express server object
*/
const initServices = (app) => {
const {
logger,
sqsApi,
cityDb,
customerDb
} = app.locals;
app.locals.city = new City({
logger, sqsApi, cityDb
});
app.locals.hello = new Hello({
logger, sqsApi, customerDb
});
};
/**
* collect all initiations in an array
*/
const inits = [
initDB,
initApi,
initServices
];
/**
* Instantiating core server class
* assign config, inits, routes
* config is get from importing from config folder
* router is get from importing the router folder
* other parameter that can be set is an array of middlewares
*/
const server = new Server({
config,
inits,
routes
});
/**
* Run server
*/
server.listen();
/**
* create function to gracefully stop the service
*/
const stopServer = (signal) => {
return server.stop(signal);
};
/**
* assign process signals to gracefully stop the service
*/
process.on('SIGINT', stopServer);
process.on('SIGTERM', stopServer);
/**
* exporting the server to be used in the lambda.js functions
*/
module.exports = server;
What happens behind the scene in Server.js
class Server {
constructor(opts) {
Object.assign(this, opts);
/**
* instantiating express.js and assign to this.app
* */
this.app = express();
/**
* assign config sent from server orchestration to app.locals.config
* so it can be accessed from any requests (to access just call req.app.locals.config)
*/
this.app.locals.config = this.config;
/**
* create logger using bunyan.createLogger
* assign to app.locals.logger to be used from any requests (to access just call req.app.locals.logger)
*/
this.logger = createLogger(this.config.logger);
this.app.locals.logger = this.logger;
/**
* assign bodyParser to the express server
* so it can read any body payload that sent through requests
*/
this.app.use(bodyParser.json());
this.app.use(bodyParser.urlencoded({ extended: true, limit: '25mb' }));
/**
* log every incoming requests
*/
this.app.use(logRequest);
/**
* assign any middlewares given to the server
*/
if (this.middlewares && this.middlewares && this.middlewares.length) {
this.middlewares.forEach(middleware => this.app.use(middleware));
}
/**
* assign swagger documents and set /docs to be the path for accessing swagger
*/
if (swaggerDocs) {
this.app.use('/docs', swaggerUi.serve, swaggerUi.setup(swaggerDocs));
}
/**
* assign any routes given to the server
*/
if (this.routes && this.routes.length) {
this.routes.forEach(route => this.app.use(route));
}
/**
* assign errorHandler to catch and send any custom error assigns in the code
*/
this.app.use(errorHandler);
/**
* log any response sent to the clients or any other services
*/
this.app.use(logResponse);
}
async listen() {
/**
* assign any initializations given to the server
*/
if (this.inits && this.inits.length) {
try {
await this.inits.reduce((p, init) => p.then(() => init(this.app)), Promise.resolve());
} catch (error) {
this.logger.error({ error }, 'failed on initializations process');
throw error;
}
}
/**
* run server by listening to the port given in the config files
*/
return new Promise((resolve) => {
this.server = this.app.listen(this.config.port, () => {
this.logger.info(`${this.config.name} is listening to ${this.config.host}:${this.config.port}`);
return resolve();
});
});
}
async stop(signal) {
/**
* log server as shutdown process and then close the server
*/
this.logger.info({ event: 'shutdown', signal });
this.server.close();
}
}
other usage can be seen in the representatives folder and files available in current project
Versioning
v.1.0.0
initial works
Authors
- muslimi