configureApplication
The single entry point that wires controllers, middlewares, auth, logging, OpenAPI and Scalar onto an Express application.
configureApplication(app, options) is where every moving part of exjs-controllers is registered against an Application. It is async because controller discovery may read from disk.
import { createApplication } from 'exjs-controllers/http/application'
import { configureApplication } from 'exjs-controllers/config/configureApplication'
const app = createApplication()
await configureApplication(app, {
controllers: [UsersController, OrdersController],
logger: { logFormat: 'pretty' },
openapi: {
documentation: { info: { title: 'My API', version: '1.0.0' } }
},
enableScalar: true
})
app.listen(3000)What it does, in order
- Resolves the controller list — either
options.controllersor via Controller Discovery. - Mounts a tiny middleware that ensures every request carries an
HttpRequestshape (locals,cookies). - Mounts the HTTP logger middleware if
loggeris set. - For every
@JsonController(prefix), mountsexpress.json()scoped toprefix. - Applies user-defined middlewares from
middlewares. - Serves the OpenAPI JSON at
openapi.documentPath(default/docs/openapi.json) whenopenapiis set — or one JSON per entry inopenapi.documents. - Mounts Scalar at
scalar.referencePath(default/docs) whenenableScalar: true— or one UI per document. - Registers every controller's routes, wiring the authentication middleware where needed.
- Mounts
errorHandlerlast, if provided.
Options reference
interface ExpressServerOptions {
controllers?: ControllerClass[]
controllerDiscovery?: ControllerDiscoveryOptions
authentication?: AuthenticationConfig
logger?: HttpLoggerOptions | false
middlewares?: MiddlewareRegistration[]
errorHandler?: ErrorMiddleware
openapi?: {
documentPath?: string
documentation: OpenApiDocumentationOptions
documents?: Record<string, OpenApiDocumentOptions>
}
scalar?: ScalarConfigurationOptions
enableScalar?: boolean
}controllers
Explicit list of controller classes. When provided, takes precedence over discovery.
controllers: [UsersController, OrdersController]controllerDiscovery
Used when controllers is omitted. See Controller Discovery.
controllerDiscovery: {
rootDir: process.cwd(),
directories: ['src', 'dist/src']
}authentication
Plug in your principal resolver, authorization checker and OpenAPI security schemes. Full reference in Authentication.
logger
Pass false to disable logging. Otherwise, pass an HttpLoggerOptions object — see Logger.
logger: {
logFormat: 'pretty',
filePath: 'logs/app.log',
correlationIdHeaderName: 'x-correlation-id'
}middlewares
Express middlewares applied before controllers. Each entry is { path, handlers }. Use path: '/' (or '') to mount globally.
import helmet from 'helmet'
import cors from 'cors'
middlewares: [
{ path: '/', handlers: [helmet()] },
{ path: '/api', handlers: [cors({ origin: 'https://example.com' })] }
]errorHandler
Standard Express 5 error handler (error, request, response, next) => void. Mounted last so it sees every framework error.
errorHandler: (error, _req, res, _next) => {
const status = (error as { status?: number }).status ?? 500
res.status(status).json({ message: (error as Error).message })
}openapi
Triggers generation of the OpenAPI document. The minimum is documentation.info.title and documentation.info.version.
openapi: {
documentPath: '/internal/openapi.json', // default: '/docs/openapi.json'
documentation: {
info: { title: 'My API', version: '1.0.0' },
components: {
securitySchemes: {
bearerAuth: { type: 'http', scheme: 'bearer', bearerFormat: 'JWT' }
}
},
security: [{ bearerAuth: [] }]
}
}Add documents to split routes into separate documents by group. Each entry accepts documentPath, referencePath, groups, info and security:
openapi: {
documentation: { info: { title: 'My API', version: '1.0.0' } },
documents: {
default: {}, // routes without a group
admin: { info: { title: 'Admin API', version: '1.0.0' } } // @Controller(prefix, { group: 'admin' })
}
}See Multiple documents for the resolution and path rules.
enableScalar
Mounts the Scalar API reference UI at /docs (configurable via scalar.referencePath). Requires openapi.documentation to be set — otherwise bootstrap throws.
scalar
Customise the Scalar runtime — override servers, change the reference path, configure authentication, intercept requests with onBeforeRequest. Detailed in Scalar.
Programmatic OpenAPI
generateOpenApiDocument(controllers, options) is exported separately if you want to build the spec without starting the server:
import { generateOpenApiDocument } from 'exjs-controllers/openapi/generateOpenApiDocument'
const document = generateOpenApiDocument([UsersController], options)
await writeFile('openapi.json', JSON.stringify(document, null, 2))