Skip to content

Commit f94d09e

Browse files
committed
move swagger outside express init to prevent memory leak in jest
1 parent b5801bb commit f94d09e

File tree

2 files changed

+45
-39
lines changed

2 files changed

+45
-39
lines changed

src/app.ts

+10-39
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
// eslint-disable-next-line simple-import-sort/imports
22
import 'reflect-metadata';
3-
import { CORS_ORIGINS, CREDENTIALS, DBURL, isProduction, PORT, SENTRY_DSN, jwtStrategy } from './config';
3+
import { CORS_ORIGINS, CREDENTIALS, MONGO_URI, DATABASE, isProduction, PORT, SENTRY_DSN, jwtStrategy } from './config';
44

55
import * as Sentry from '@sentry/node';
66
import bodyParser from 'body-parser';
7-
import { defaultMetadataStorage as classTransformerDefaultMetadataStorage } from 'class-transformer/cjs/storage';
8-
import { validationMetadatasToSchemas } from 'class-validator-jsonschema';
7+
98
import cookieParser from 'cookie-parser';
109
import cors from 'cors';
1110
import express, { Application, ErrorRequestHandler, RequestHandler } from 'express';
@@ -14,9 +13,7 @@ import hpp from 'hpp';
1413
import http from 'http';
1514
import mongoose from 'mongoose';
1615
import passport from 'passport';
17-
import { getMetadataArgsStorage, useExpressServer } from 'routing-controllers';
18-
import { routingControllersToSpec } from 'routing-controllers-openapi';
19-
import swaggerUi from 'swagger-ui-express';
16+
import { useExpressServer } from 'routing-controllers';
2017
import xss from 'xss-clean';
2118

2219
import handlingErrorsMiddleware from './middlewares/handlingErrors.middleware';
@@ -26,16 +23,17 @@ let serverConnection: http.Server;
2623
export default class App {
2724
private app: Application;
2825
private port: string | number;
26+
private controllers: Function[] = [];
2927

3028
constructor(controllers: Function[]) {
3129
this.app = express();
3230
this.port = PORT || 8080;
31+
this.controllers = controllers;
3332

3433
this.initSentry();
3534
this.initMiddlewares();
3635
this.initRoutes(controllers);
3736

38-
this.initSwagger(controllers);
3937
this.initHandlingErrors();
4038
}
4139

@@ -74,37 +72,6 @@ export default class App {
7472
});
7573
}
7674

77-
private initSwagger(controllers: Function[]) {
78-
const schemas = validationMetadatasToSchemas({
79-
classTransformerMetadataStorage: classTransformerDefaultMetadataStorage,
80-
refPointerPrefix: '#/components/schemas/',
81-
});
82-
83-
const routingControllersOptions = {
84-
controllers: controllers,
85-
};
86-
87-
const storage = getMetadataArgsStorage();
88-
const spec = routingControllersToSpec(storage, routingControllersOptions, {
89-
components: {
90-
schemas,
91-
securitySchemes: {
92-
basicAuth: {
93-
scheme: 'basic',
94-
type: 'http',
95-
},
96-
},
97-
},
98-
info: {
99-
description: 'API Generated with `routing-controllers-openapi` package',
100-
title: 'API',
101-
version: '1.0.0',
102-
},
103-
});
104-
105-
this.app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(spec));
106-
}
107-
10875
private initHandlingErrors() {
10976
if (isProduction) {
11077
// The error handler must be before any other error middleware and after all controllers
@@ -114,7 +81,7 @@ export default class App {
11481
}
11582

11683
static async initDB() {
117-
await mongoose.connect(DBURL);
84+
await mongoose.connect(`${MONGO_URI}/${DATABASE}`);
11885
}
11986

12087
static async closeDB() {
@@ -146,4 +113,8 @@ export default class App {
146113
public getServer = () => {
147114
return this.app;
148115
};
116+
117+
public get getControllers() {
118+
return this.controllers;
119+
}
149120
}

src/index.ts

+35
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,43 @@
1+
import { defaultMetadataStorage as classTransformerDefaultMetadataStorage } from 'class-transformer/cjs/storage';
2+
import { validationMetadatasToSchemas } from 'class-validator-jsonschema';
3+
import { getMetadataArgsStorage } from 'routing-controllers';
4+
import { routingControllersToSpec } from 'routing-controllers-openapi';
5+
import swaggerUi from 'swagger-ui-express';
6+
17
import { AuthControllerV1, UserControllerV1 } from '@v1/index';
28

39
import App from './app';
410

11+
function initSwagger(server: App) {
12+
const schemas = validationMetadatasToSchemas({
13+
classTransformerMetadataStorage: classTransformerDefaultMetadataStorage,
14+
refPointerPrefix: '#/components/schemas/',
15+
});
16+
const routingControllersOptions = {
17+
controllers: server.getControllers,
18+
};
19+
const storage = getMetadataArgsStorage();
20+
const spec = routingControllersToSpec(storage, routingControllersOptions, {
21+
components: {
22+
schemas,
23+
securitySchemes: {
24+
basicAuth: {
25+
scheme: 'basic',
26+
type: 'http',
27+
},
28+
},
29+
},
30+
info: {
31+
description: 'API Generated with `routing-controllers-openapi` package',
32+
title: 'API',
33+
version: '1.0.0',
34+
},
35+
});
36+
server.getServer().use('/api-docs', swaggerUi.serve, swaggerUi.setup(spec));
37+
}
38+
539
const server = new App([AuthControllerV1, UserControllerV1]);
40+
initSwagger(server);
641

742
(async () => {
843
await server.initServerWithDB();

0 commit comments

Comments
 (0)