Expressify’s controller factory. This module exports a function you can use to create and configure a controller factory.


  • basePath: factory will try to resolve modules relative to this path
  • middlewares: a dictionary of middlewares where the key is a name you choose, you use the same key to configure this middleware later. The value should be a middleware factory function that takes an options object and returns the middleware.
  • defaults: a dictionary with default options for middlewares defined in middlewares. These provide a default config that can be overwritten by the controlller configuration.

Controller modules

The factory function that you created with the above options takes one argument, module, which is:

  • a string that will be resolved relative to basePath or if that fails with a regular require call.
  • an object representing either a controller config or a controller module.

Controller modules should either export a controller config object or a dictionary of controller config objects. A middleware stack or a dictionary of middleware stacks will be returned.

Controller config objects should at least have a controller key that has a controller function as value. This function will be the last in the middleware stack. Other keys are meant for configuring middlewares, their values should be objects that will replace the defaults from earlier and be passed to the relevant middleware factory. Alternatively the other keys can have functions as values, these functions will be passed the defaults for the specified key and should return an object with the new configuration. A controller function may return a rejected promise which will automatically be passed along to the error middlewares.

It’s also possible to disable a middleware for a specific controller by passing false as the middleware’s option value instead of a config object.

// ./controllers/foo.js

module.exports = {
    get: {
        controller: (req, res) => {},
        authentication: false, // Disable the authentication middleware
        validation: { // Replace validation configuration
            query: Joi => Joi.object().keys({ foo: Joi.string() })
        hal: (defaults) => ({ // merge configuration with defaults
            name: 'foo'

// ./index.js

const app = require('express')();
const createControllerFactory = require('@ambassify/expressify/controller');
const controllerFactory = createControllerFactory({
    basePath: './controllers',
    middlewares: {
        authentication: require('@ambassify/expressify/middleware/authentication'),
        validation: require('@ambassify/expressify/middleware/validation')
    defaults: {
        validation: { joi: MyCustomJoi } // default option for middleware

app.get('/foo', ...controller('foo').get);