nope/lib/open-api/startOpenApiBackend.ts
2020-11-12 17:07:05 +01:00

120 lines
3.2 KiB
TypeScript

/**
* @author Martin Karkowski
* @email m.karkowski@zema.de
* @create date 2020-11-12 11:21:41
* @modify date 2020-11-12 11:21:43
* @desc [description]
*/
import * as bodyParser from "body-parser";
import * as cors from 'cors';
import * as express from "express";
import { initialize } from "express-openapi";
import { readFile } from "fs/promises";
import { assignIn } from 'lodash';
import { join } from "path";
import "reflect-metadata";
import { Logger } from 'winston';
import { INopeDispatcher } from "../types/nope/nopeDispatcher.interface";
import { getBackendAccesors } from './getBackendAccessors';
/**
* Function to generate the Base Api Documentation
* @param title The Title of the API
* @param version The Version
* @param basePath A Basepath for the API
*/
function _genApiDoc(title: string, version: string, basePath: string, definitions: any = {}){
// Default API Doc
const apiDoc = {
swagger: '2.0',
basePath: basePath || '/v1',
info: {
title,
version
},
definitions,
paths: {}
};
return apiDoc;
}
/**
* Function to start a Open-API-Server
* @param _dispatcher The Dispatcher, which should be used.
* @param options Options for the Server
*/
export async function startOpenApiBackend(
_dispatcher: INopeDispatcher,
options: {
port?: number,
backendPort?: number,
basePath?: string,
logger?: Logger,
} = {}) {
const app: express.Application = (express as any)();
// Define the Default Options
const defaults = {
port: 3001,
backendPort: 3002,
basePath: '/api'
}
// Mix the Options.
const opts = assignIn(defaults, options);
app.use(bodyParser.json());
app.use(cors());
let _definition = {};
try {
// Extract the Elements provided in the API-Document.
_definition = JSON.parse(await readFile(join(__dirname, 'apidoc.json'), {
encoding: 'utf8'
})).definitions;
} catch(e){
if (opts.logger) {
opts.logger.error('cant parse apidoc.json');
}
}
initialize({
apiDoc: _genApiDoc('Backend API', '1.0.0', opts.basePath, _definition),
app,
paths: './dist/open-api',
routesGlob: '**/*.{ts,js}',
routesIndexFileRegExp: /(?:index)?\.[tj]s$/,
dependencies: {
_dispatcher
},
});
app.use(((err, req, res, next) => {
res.status(err.status).json(err);
}) as express.ErrorRequestHandler);
const server = app.listen(opts.port);
const accessor = getBackendAccesors(app);
if (options.logger) {
options.logger.info('Server Running on http://localhost:' + opts.port.toString() + opts.basePath);
options.logger.info('API Documentation available on http://localhost:' + opts.port.toString() + opts.basePath + '/api-docs');
options.logger.debug('Checkout http://localhost:3000/docs')
}
return {
app,
// Accessor for the Server
accessor,
// Function to extract the Definitions.
definitionUri: opts.basePath + '/api-docs',
// Function to Close the Server
close() {
server.close();
}
}
}