rest-api-starter
Version:
Rest API starter kit.
122 lines (105 loc) • 4.1 kB
JavaScript
/**
* Created by svinci on 8/18/16.
*/
;
const express = require('express');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const compression = require('compression');
const configuration = require('config');
const uuid = require('uuid');
const localStore = require('./local-store');
const logger = require('./logger')('server-initialization');
const configureLoggingFilter = (app) => {
const transactionHeaderName = configuration.get('app.http.transactionHeader');
app.use((request, response, next) => {
localStore.create(() => {
const transactionId = request.get(transactionHeaderName) || uuid.v4().substr(0, 7);
response.append(transactionHeaderName, transactionId);
localStore.putValue('req', request);
localStore.putValue('res', response);
localStore.putValue('tid', transactionId);
logger.info(`Received request ${request.method} at ${request.url}`);
next();
});
});
};
const configureCompression = (app) => {
const compressionEnabled = configuration.has('app.http.compression') ? configuration.get('app.http.compression') : true;
if (compressionEnabled) {
app.use(compression());
}
};
const configureCookieParser = (app) => {
const cookieParserEnabled = configuration.has('app.http.cookies') ? configuration.get('app.http.cookies') : true;
if (cookieParserEnabled) {
app.use(cookieParser(configuration.get('app.http.secret')));
}
};
const configureJsonBodyParser = (app) => {
const jsonBodyParserEnabled = configuration.has('app.http.json') ? configuration.get('app.http.json') : true;
if (jsonBodyParserEnabled) {
app.use(bodyParser.json());
}
};
const configureNotFoundHandler = (app, customNotFoundHandler) => {
const defaultNotFoundHandler = (req, res) => {
logger.warn(`Returning 404 for url: ${req.url}.`);
res.status(404).send({
'status': 404,
'message': 'url/method combination not found',
'detail': {
'url': req.url,
'method': req.method
}
});
};
app.use(customNotFoundHandler || defaultNotFoundHandler);
};
const configureErrorHandler = (app, customErrorHandler) => {
const defaultErrorHandler = (err, req, res, next) => {
if (err.name === 'validation.error') {
logger.error(err.name);
res.status(400).send({
'status': 400,
'message': err.name,
'detail': err.errors
});
} else if (err.name && err.name === 'document.not.found') {
logger.error(err.message);
res.status(404).send({
'status': 404,
'message': err.message,
'detail': err.detail
});
} else {
logger.error(`Unhandled error for request ${req.method} at ${req.url}. Err: ${err}.`);
res.status(500).send({
'status': 500,
'message': 'unhandled error',
'detail': err.toString()
});
}
};
app.use(customErrorHandler || defaultErrorHandler);
};
const newServer = (router, customNotFoundHandler, customErrorHandler) => {
logger.info('Starting server...');
const start = new Date();
const app = new express();
configureLoggingFilter(app);
configureCompression(app);
configureCookieParser(app);
configureJsonBodyParser(app);
router(app);
configureNotFoundHandler(app, customNotFoundHandler);
configureErrorHandler(app, customErrorHandler);
const port = configuration.get('app.http.port');
const host = configuration.get('app.http.host');
const queue = configuration.get('app.http.queue');
return app.listen(port, host, queue, () => {
logger.info(`Server started in ${new Date() - start}ms`);
logger.info(`Listening on port ${port} and host ${host}. Queue: ${queue}`);
});
};
module.exports = newServer;