Skip to content
/ hmpo-app Public

Bootstrap module for HMPO framework

License

Notifications You must be signed in to change notification settings

HMPO/hmpo-app

Repository files navigation

hmpo-app forms framework bootstrap

Usage

Simple usage

const { setup } = require('hmpo-app');
const { router } = setup();

router.use('/', require('./routes/example'));

Extended usage

const {
    setup,
    featureFlag,
    config,
    logger,
    redisClient,
    linkedFiles
} = require('hmpo-app');

const {
    app,
    staticRouter,
    router,
    errorRouter
} = setup({
    option: 'value'
});

See example app for more details

Usage Details

  • Returned from require('hmpo-app').
  • setup(options) Bootstraps the app. Run this as early on as possible to init the logger before it is used.

Parameters

  • options (Object) - An object containing the options for configuring the application. Defaults to { middlewareSetupFn: undefined } if not provided.

Returns

  • app - the top-level express app.
  • staticRouter - an express router before session is initialised.
  • router - an express router after session is initialised.
  • errorRouter - an express router before the generic error handling used to handle custom errors.

More info on the options Object

Any of these options (except for config) can also be specified in a config file. The options passed to setup() override the options loaded from config files.

config - if false no config will be loaded.

  • APP_ROOT - Override app root directory detection
  • files = 'config/default(.json|.yaml|.yml)' - Array of config files to try to load. Missing files will fail silently.
  • envVarName = 'HMPO_CONFIG' - Environment variable to parse to override config values.
  • commandLineSwitch = '-c' - Command line switch to load additional config files.
  • merge = true - Merge new config with config from previous calls to setup.

env = NODE_ENV - Environment variable or 'development' environment.

port = 3000 - Port to bind to. If false the app will not listen to a port. host = '0.0.0.0' - Host to bind to.

logs - See hmpo-logger for options passed to logger. See hmpo-logger for defaults. If false no logger is initialised.

requestLogging = true - Enable request logging (excluding public static files).

redis - If false redis is not initialised.

  • connectionString - Connection url used for connecting to a redis instance.
  • host - Host name for connecting to a redis instance.
  • port = 6379 - Port for connection to a redis instance.
  • ...otherOptions - Any other options are passed to redis.
  • If neither connectionString or host and port are specified, an in-memory redis is used.

errors - If false no error handler is set

  • startUrl = '/' - Url to redirect to if a deep page is accessed as a new browser. Can be a function(req, res).
  • pageNotFoundView = 'errors/page-not-found' - View to render for page not found.
  • sessionEndedView = 'errors/session-ended' - View to render if session is not found/expired.
  • defaultErrorView = 'errors/error' - View to render for other errors.

urls

  • public = '/public' - Base URL for public static assets.
  • publicImages = '/public/images' - Base URL for public sttic images.
  • version = '/version' - Base URL for version endpoint, or false to disable.
  • healthcheck = '/healthcheck' - Base URL for healthcheck endpoint, or false to disable.

publicDirs = ['public'] - Array of paths to mount on the public route, relative to APP_ROOT. publicImagesDirs = ['assets/images'] - Array of paths to mount on the public images route, relative to APP_ROOT. publicOptions = {maxAge: 86400000} - Options passed to the express static middleware.

views = 'views' - Array of view directories relative to APP_ROOT.

nunjucks - Options passed to nunjucks templating contructor, or false to disable

  • dev = env==='development' - Run nunjucks in developer mode for more verbose errors.
  • noCache = env==='development' - Don't cache compiled template files.
  • watch = env==='development' - Watch for changes to template files.
  • ...otherOptions - Any other options are passed to nunjucks.configure

locales = '.' - Array of locales base directories (containing a 'locales' directory) relative to APP_ROOT.

translation - Options passed to hmpo-i18n translation library, or false to disable.

  • noCache = env==='development' - Don't cache templated localisation strings.
  • watch = env==='development' - Watch for changes to localisation files.
  • allowedLangs = ['en','cy'] - Array of allowed languages.
  • fallbackLang = ['en'] - Array of languages to use if translation not found is current language.
  • cookie = {name: 'lang'} - Cookie settings to use to store current language.
  • query = 'lang' - Query parameter to use to change language, or false to disable.
  • ...otherOptions - Any other options are passed to hmpo-i18n.

modelOptions - Configuration for model options helper to be used with hmpo-model.

  • sessionIDHeader = 'X-SESSION-ID' - Session ID request header to pass through to models.
  • scenarioIDHeader = 'X-SCENARIO-ID' - Stub scenario ID request header to pass through to models.

helmet - Configuration for Helmet, or false to only use frameguard and disable x-powered-by.
disableCompression = false - disable compression middleware.

cookies - Configuration for cookie parsing middleware.

Middleware returned from require('hmpo-app').

getFlags(req) - Return all session and config feature flags.

isEnabled(flag, req) - Check if a feature flag is enabled in session or config.

isDisabled(flag, req) - Check if a feature flag is disabled in session or config.

redirectIfEnabled(flag, url) - Middleware to redirect if a flag is enabled.

redirectIfDisabled(flag, url) - Middleware to redirect if a flag is disabled.

routeIf(flag, handlerIf, handlerElse) - Middleware to run different handler depending on status of a feature flag.

Example Usage

const { featureFlag } = require('hmpo-app');

const enabledMiddleware = (req, res, next) => res.send('flag enabled');
const disabledMiddleware = (req, res, next) => res.send('flag disabled');

router.use(featureFlag.routeIf('flagname', enabledMiddleware, disabledMiddleware));

A config helper returned from require('hmpo-app').

Returns

defaultFiles - An array of default config files: [ 'config/default.json', 'config/default.yaml', 'config/default.yml' ];

setup(configOptions?) - A function for config setup that takes an options Object containing possible params:

  • { APP_ROOT, seed, files = defaultFiles, envVarName = 'HMPO_CONFIG', commandLineSwitch = '-c', merge = true, _commandLineArgs = process.argv, _environmentVariables = process.env }
  • Defaults to empty Object if no options provided.

get(path, defaultIfUndefined) / config(path, defaultIfUndefined) - Get a value from loaded config by dot separated path, or a default if not found or undefined. If any part of the path is not found, the default will be returned.

Example Usage

const { config } = require('hmpo-app');

let defaultFiles = config.defaultFiles;

// Setup config
if (options.config !== false) config.setup(options.config);

const value = config.get('config.path.string', 'default value');

Due to the way config.js uses Object.assign(), you can use config(path, defaultIfUndefined) and config.get(path, defaultIfUndefined) interchangeably - depending on which you find better for readability.

E.g.

const value = config('config.path.string', 'default value');

// OR

const value = config.get('config.path.string', 'default value');

Returns

setup(options?) - Setup the logger by passing an options Object. If no options are supplied it will default to checking config.get('logs', {}). This passes the provided options directly to hmpoLogger.config().

get(name?, level?) / logger(name?, level?) - Get a new logger with an optional name (defaults to :hmpo-app) and an optional level (defaults to 1).

Example Usage

const { logger } = require('hmpo-app');

logger.setup(); // Setup from config.

// or

logger.setup({ foo: 'bar' });   // Setup from options

const log = logger(':name');

log.info('log message', { req, err, other: 'metedata' });

// or

logger().info('log message', { req, err, other: 'metedata' });

Due to the way logger.js uses Object.assign(), you can use logger(name) and logger.get(name) interchangeably - depending on which you find better for readability.

E.g.

const myLogger1 = logger('logger1');

// OR

const myLogger2 = logger.get('logger2');

Returns

redisClient() / getClient() - Returns a redis client.

client - The redisClient, defaults to null.

setup(options?) - Returns a modified redisClient.client.

  • Closes an existing client using provided close() and creates a new one using the provided options.
  • All options are passed to redis.createClient(). See Node Redis Docs for more info.
  • If no options specified, this will default to checking config.get('redis', {}).
  • options assumes the following parameters: { connectionString, host, port = 6379, ...redisOptions }

close(callback) - Quits a redisClient if it exists / is connected, then sets redisClient.client = null. Finally, fires the provided callback function.

Due to the way redis-client.js uses Object.assign(), you can use redisClient() and redisClient.getClient() interchangeably - depending on which you find better for readability.

Example Usage

const { redisClient } = require('hmpo-app');

// Setup the Redis client
redisClient.setup({
    connectionString: 'redis://localhost:6379',
    // OR
    host: 'localhost',
    port: 6379,
    // Optional: any other redis.createClient options
    socket: {
        reconnectStrategy: retries => Math.min(retries * 50, 2000)
    }
});

// Get the Redis client instance
const client = redisClient(); // same as redisClient.getClient()

client.set('foo', 'bar');
client.get('foo').then(console.log); // Outputs: bar

// Gracefully close the client when shutting down
redisClient.close(() => {
    console.log('Redis connection closed');
});

Further Examples