redis-smq-rest-api
Version:
REST API for RedisSMQ: OpenAPI 3 schema and Swagger UI for managing queues, messages, and consumers.
111 lines • 4.67 kB
JavaScript
import { bodyParser } from '@koa/bodyparser';
import cors from '@koa/cors';
import { asValue } from 'awilix';
import bluebird from 'bluebird';
import * as http from 'http';
import Koa from 'koa';
import mount from 'koa-mount';
import koaStatic from 'koa-static';
import { join } from 'path';
import { RedisSMQ } from 'redis-smq';
import { createLogger } from 'redis-smq-common';
import { getAbsoluteFSPath as swaggerUiDistPath } from 'swagger-ui-dist';
import tmp from 'tmp';
import { constants } from './config/constants.js';
import { parseConfig, } from './config/index.js';
import { Container } from './container/Container.js';
import { buildSwaggerUiHtml } from './helpers/swagger-ui.js';
import { errorHandlerMiddleware } from './lib/errors/middlewares/errorHandlerMiddleware.js';
import { generateOpenApiDocument, saveOpenApiDocument, } from './lib/openapi-spec/builder.js';
import { registerResources } from './lib/router/index.js';
import { routing } from './router/routing.js';
const RedisSMQAsync = bluebird.promisifyAll(RedisSMQ);
const tmpAsync = bluebird.promisifyAll(tmp);
export class RedisSMQRestApi {
app;
config;
runHttpServer;
logger;
httpServer;
bootstrapped = false;
constructor(config = {}, runHttpServer = true) {
this.app = new Koa();
this.runHttpServer = runHttpServer;
this.config = parseConfig(config);
Container.registerServices();
const container = Container.getInstance();
container.register({ config: asValue(this.config) });
this.logger = createLogger(this.config.logger, 'RedisSMQRestApi');
this.httpServer = http.createServer(this.app.callback());
}
async initApplicationMiddlewares() {
this.app.use((ctx, next) => {
ctx.scope = Container.getInstance().createScope();
return next();
});
this.app.use(errorHandlerMiddleware);
this.app.use(bodyParser());
this.app.use(cors({
origin: '*',
}));
}
async initOpenApi() {
const { basePath } = this.config.apiServer;
const openApiFilename = constants.openApiDocumentFilename;
this.logger.info('Initializing OpenAPI...');
const spec = await generateOpenApiDocument(routing, basePath);
const tmpDir = await tmpAsync.dirAsync();
await saveOpenApiDocument(spec, tmpDir);
const uiAssetsFsPath = swaggerUiDistPath();
this.app.use(mount(join(basePath, '/swagger/ui'), koaStatic(uiAssetsFsPath)));
this.app.use(mount(join(basePath, '/swagger/assets'), koaStatic(tmpDir)));
const specUrl = join(basePath, '/swagger/assets', openApiFilename);
const uiAssetsUrl = join(basePath, '/swagger/ui');
const html = buildSwaggerUiHtml(specUrl, uiAssetsUrl);
this.app.use(mount(join(basePath, '/swagger'), (ctx) => {
if (ctx.path === '/' || ctx.path === '') {
ctx.type = 'text/html; charset=utf-8';
ctx.body = html;
}
}));
}
async initRouting() {
this.logger.info('Registering routes...');
const appRouter = await registerResources(routing);
this.app.use(appRouter.routes());
this.app.use(appRouter.allowedMethods());
}
async bootstrap() {
if (this.bootstrapped)
return;
await RedisSMQAsync.initializeAsync(this.config.redis);
await this.initApplicationMiddlewares();
await this.initRouting();
await this.initOpenApi();
this.bootstrapped = true;
}
async run() {
await this.bootstrap();
if (!this.runHttpServer)
return;
const { port, basePath } = this.config.apiServer;
await new Promise((resolve) => this.httpServer.listen(port, () => resolve()));
this.logger.info(`RedisSMQ REST API server is running on http://localhost:${port}...`);
const baseURL = `http://127.0.0.1:${port}${basePath === '/' ? '' : basePath}`;
this.logger.info(`OpenAPI specs are available at ${baseURL}/swagger/assets/${constants.openApiDocumentFilename}`);
this.logger.info(`SWAGGER UI is accessible from ${baseURL}/swagger`);
}
async getApplication() {
await this.bootstrap();
return this.app.callback();
}
async shutdown() {
if (this.httpServer.listening) {
await new Promise((resolve) => this.httpServer.close(resolve));
}
await Container.getInstance().dispose();
await RedisSMQAsync.shutdownAsync();
this.logger.info('RedisSMQ HTTP API has been shutdown.');
}
}
//# sourceMappingURL=index.js.map