| 88 | * @returns {Promise<any>} The express application. |
| 89 | */ |
| 90 | export async function createApp( |
| 91 | AppController: Class<IAppController>, |
| 92 | options: CreateAppOptions = {}, |
| 93 | ): Promise<any> { |
| 94 | const app = options.expressInstance || express(); |
| 95 | |
| 96 | // Add optional pre-middlewares. |
| 97 | for (const middleware of options.preMiddlewares || []) { |
| 98 | app.use(middleware); |
| 99 | } |
| 100 | |
| 101 | // Create the service and controller manager. |
| 102 | const services = options.serviceManager || new ServiceManager(); |
| 103 | app.foal = { services }; |
| 104 | |
| 105 | // Retrieve the logger. |
| 106 | const logger = services.get(Logger); |
| 107 | |
| 108 | // Allow to add log context. |
| 109 | app.use((req: any, res: any, next: (err?: any) => any) => { |
| 110 | logger.initLogContext(next); |
| 111 | }); |
| 112 | |
| 113 | // Generate a unique ID for each request. |
| 114 | app.use((req: any, res: any, next: (err?: any) => any) => { |
| 115 | const requestId = req.get('x-request-id') || randomUUID(); |
| 116 | |
| 117 | req.id = requestId; |
| 118 | logger.addLogContext({ requestId }); |
| 119 | |
| 120 | next(); |
| 121 | }); |
| 122 | |
| 123 | // Log requests. |
| 124 | const shouldLogHttpRequests = Config.get('settings.logger.logHttpRequests', 'boolean', true); |
| 125 | if (shouldLogHttpRequests) { |
| 126 | const getHttpLogParams = options.getHttpLogParams || getHttpLogParamsDefault; |
| 127 | app.use(morgan( |
| 128 | (tokens: any, req: any, res: any) => JSON.stringify(getHttpLogParams(tokens, req, res)), |
| 129 | { |
| 130 | stream: { |
| 131 | write: (message: string) => { |
| 132 | const data = JSON.parse(message); |
| 133 | logger.info(`${httpRequestMessagePrefix}${data.method} ${data.url}`, data); |
| 134 | }, |
| 135 | }, |
| 136 | } |
| 137 | )) |
| 138 | } |
| 139 | |
| 140 | app.use(protectionHeaders); |
| 141 | |
| 142 | // Serve static files. |
| 143 | app.use( |
| 144 | Config.get('settings.staticPathPrefix', 'string', ''), |
| 145 | express.static(Config.get('settings.staticPath', 'string', 'public'), { |
| 146 | cacheControl: Config.get('settings.staticFiles.cacheControl', 'boolean') |
| 147 | }) |