Browse Source

Add nestjs framework with fastify (#5503)

* Add nestjs framework with fastify

* Merge nestjs frameworks, update deps
Patryk Strugacz 5 years ago
parent
commit
e026dd6753
28 changed files with 427 additions and 371 deletions
  1. 2 1
      frameworks/TypeScript/nest/.dockerignore
  2. 23 0
      frameworks/TypeScript/nest/.eslintrc.js
  3. 3 2
      frameworks/TypeScript/nest/.gitignore
  4. 1 4
      frameworks/TypeScript/nest/.prettierrc
  5. 83 38
      frameworks/TypeScript/nest/benchmark_config.json
  6. 13 0
      frameworks/TypeScript/nest/nestjs-fastify-mysql.dockerfile
  7. 13 0
      frameworks/TypeScript/nest/nestjs-fastify.dockerfile
  8. 6 3
      frameworks/TypeScript/nest/nestjs-mysql.dockerfile
  9. 6 3
      frameworks/TypeScript/nest/nestjs.dockerfile
  10. 32 29
      frameworks/TypeScript/nest/ormconfig.js
  11. 37 49
      frameworks/TypeScript/nest/package.json
  12. 0 22
      frameworks/TypeScript/nest/src/app.controller.spec.ts
  13. 53 5
      frameworks/TypeScript/nest/src/app.controller.ts
  14. 8 5
      frameworks/TypeScript/nest/src/app.module.ts
  15. 68 2
      frameworks/TypeScript/nest/src/app.service.ts
  16. 0 15
      frameworks/TypeScript/nest/src/bench/bench.controller.spec.ts
  17. 0 56
      frameworks/TypeScript/nest/src/bench/bench.controller.ts
  18. 0 15
      frameworks/TypeScript/nest/src/bench/bench.module.ts
  19. 0 15
      frameworks/TypeScript/nest/src/bench/bench.service.spec.ts
  20. 0 66
      frameworks/TypeScript/nest/src/bench/bench.service.ts
  21. 10 0
      frameworks/TypeScript/nest/src/fortune.entity.ts
  22. 55 14
      frameworks/TypeScript/nest/src/main.ts
  23. 0 10
      frameworks/TypeScript/nest/src/models/fortune.entity.ts
  24. 0 10
      frameworks/TypeScript/nest/src/models/world.entity.ts
  25. 10 0
      frameworks/TypeScript/nest/src/world.entity.ts
  26. 4 0
      frameworks/TypeScript/nest/tsconfig.build.json
  27. 0 7
      frameworks/TypeScript/nest/tsconfig.spec.json
  28. 0 0
      frameworks/TypeScript/nest/views/fortunes.hbs

+ 2 - 1
frameworks/TypeScript/nest/.dockerignore

@@ -1,2 +1,3 @@
 node_modules/
 node_modules/
-dist/
+dist/
+package-lock.json

+ 23 - 0
frameworks/TypeScript/nest/.eslintrc.js

@@ -0,0 +1,23 @@
+module.exports = {
+  parser: '@typescript-eslint/parser',
+  parserOptions: {
+    project: 'tsconfig.json',
+    sourceType: 'module',
+  },
+  plugins: ['@typescript-eslint/eslint-plugin'],
+  extends: [
+    'plugin:@typescript-eslint/eslint-recommended',
+    'plugin:@typescript-eslint/recommended',
+    'prettier',
+    'prettier/@typescript-eslint',
+  ],
+  root: true,
+  env: {
+    node: true,
+  },
+  rules: {
+    '@typescript-eslint/interface-name-prefix': 'off',
+    '@typescript-eslint/explicit-function-return-type': 'off',
+    '@typescript-eslint/no-explicit-any': 'off',
+  },
+};

+ 3 - 2
frameworks/TypeScript/nest/.gitignore

@@ -1,5 +1,3 @@
-
-
 ### Node ###
 ### Node ###
 # Logs
 # Logs
 logs
 logs
@@ -25,6 +23,9 @@ typings/
 # Yarn Integrity file
 # Yarn Integrity file
 .yarn-integrity
 .yarn-integrity
 
 
+# Obsolete package-lock.json
+package-lock.json
+
 # dotenv environment variables file
 # dotenv environment variables file
 .env
 .env
 
 

+ 1 - 4
frameworks/TypeScript/nest/.prettierrc

@@ -1,7 +1,4 @@
 {
 {
   "singleQuote": true,
   "singleQuote": true,
-  "trailingComma": "all",
-  "arrowParens": "avoid",
-  "useTabs": true,
-  "tabWidth": 2
+  "trailingComma": "all"
 }
 }

+ 83 - 38
frameworks/TypeScript/nest/benchmark_config.json

@@ -1,42 +1,87 @@
 {
 {
   "framework": "nestjs",
   "framework": "nestjs",
-  "tests": [{
-    "default": {
-      "json_url": "/bench/json",
-      "plaintext_url": "/bench/plaintext",
-      "update_url": "/bench/updates?queries=",
-      "query_url": "/bench/queries?queries=",
-      "db_url": "/bench/db",
-      "fortune_url": "/bench/fortunes",
-      "port": 8080,
-      "approach": "Realistic",
-      "classification": "Micro",
-      "framework": "nestjs",
-      "language": "TypeScript",
-      "os": "Linux",
-      "orm": "Full",
-      "database": "Postgres",
-      "database_os": "Linux",
-      "display_name": "nestjs",
-      "versus": "nodejs"
-    },
-    "mysql": {
-      "json_url": "/bench/json",
-      "plaintext_url": "/bench/plaintext",
-      "update_url": "/bench/updates?queries=",
-      "query_url": "/bench/queries?queries=",
-      "db_url": "/bench/db",
-      "port": 8080,
-      "approach": "Realistic",
-      "classification": "Micro",
-      "framework": "nestjs",
-      "language": "TypeScript",
-      "os": "Linux",
-      "orm": "Full",
-      "database": "MySQL",
-      "database_os": "Linux",
-      "display_name": "nestjs",
-      "versus": "nodejs"
+  "tests": [
+    {
+      "default": {
+        "json_url": "/json",
+        "db_url": "/db",
+        "query_url": "/queries?queries=",
+        "fortune_url": "/fortunes",
+        "update_url": "/updates?queries=",
+        "plaintext_url": "/plaintext",
+        "cached_query_url": "/cached-worlds?count=",
+        "port": 8080,
+        "approach": "Realistic",
+        "classification": "Micro",
+        "framework": "nestjs",
+        "language": "TypeScript",
+        "os": "Linux",
+        "orm": "Full",
+        "database": "Postgres",
+        "database_os": "Linux",
+        "display_name": "nestjs",
+        "versus": "nodejs"
+      },
+      "mysql": {
+        "json_url": "/json",
+        "db_url": "/db",
+        "query_url": "/queries?queries=",
+        "fortune_url": "/fortunes",
+        "update_url": "/updates?queries=",
+        "plaintext_url": "/plaintext",
+        "cached_query_url": "/cached-worlds?count=",
+        "port": 8080,
+        "approach": "Realistic",
+        "classification": "Micro",
+        "framework": "nestjs",
+        "language": "TypeScript",
+        "os": "Linux",
+        "orm": "Full",
+        "database": "MySQL",
+        "database_os": "Linux",
+        "display_name": "nestjs",
+        "versus": "nodejs"
+      },
+      "fastify": {
+        "json_url": "/json",
+        "db_url": "/db",
+        "query_url": "/queries?queries=",
+        "fortune_url": "/fortunes",
+        "update_url": "/updates?queries=",
+        "plaintext_url": "/plaintext",
+        "cached_query_url": "/cached-worlds?count=",
+        "port": 8080,
+        "approach": "Realistic",
+        "classification": "Micro",
+        "database": "Postgres",
+        "framework": "nestjs",
+        "language": "TypeScript",
+        "orm": "Full",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "nestjs",
+        "versus": "nodejs"
+      },
+      "fastify-mysql": {
+        "json_url": "/json",
+        "db_url": "/db",
+        "query_url": "/queries?queries=",
+        "fortune_url": "/fortunes",
+        "update_url": "/updates?queries=",
+        "plaintext_url": "/plaintext",
+        "cached_query_url": "/cached-worlds?count=",
+        "port": 8080,
+        "approach": "Realistic",
+        "classification": "Micro",
+        "database": "MySQL",
+        "framework": "nestjs",
+        "language": "TypeScript",
+        "orm": "Full",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "nestjs",
+        "versus": "nodejs"
+      }
     }
     }
-  }]
+  ]
 }
 }

+ 13 - 0
frameworks/TypeScript/nest/nestjs-fastify-mysql.dockerfile

@@ -0,0 +1,13 @@
+FROM node:12.16.1-slim
+
+COPY ./ ./
+
+RUN npm install
+RUN npm run build
+
+ENV NODE_ENV production
+ENV DATABASE_CONFIGURATION_PROFILE=mysql
+ENV FRAMEWORK=fastify
+
+EXPOSE 8080
+CMD ["node", "dist/main"]

+ 13 - 0
frameworks/TypeScript/nest/nestjs-fastify.dockerfile

@@ -0,0 +1,13 @@
+FROM node:12.16.1-slim
+
+COPY ./ ./
+
+RUN npm install
+RUN npm run build
+
+ENV NODE_ENV production
+ENV DATABASE_CONFIGURATION_PROFILE=postgres
+ENV FRAMEWORK=fastify
+
+EXPOSE 8080
+CMD ["node", "dist/main"]

+ 6 - 3
frameworks/TypeScript/nest/nestjs-mysql.dockerfile

@@ -1,10 +1,13 @@
-FROM node:12.3.1-slim
+FROM node:12.16.1-slim
 
 
 COPY ./ ./
 COPY ./ ./
 
 
-RUN yarn install
+RUN npm install
+RUN npm run build
 
 
 ENV NODE_ENV production
 ENV NODE_ENV production
 ENV DATABASE_CONFIGURATION_PROFILE=mysql
 ENV DATABASE_CONFIGURATION_PROFILE=mysql
+ENV FRAMEWORK=express
 
 
-CMD ["yarn", "start:prod"]
+EXPOSE 8080
+CMD ["node", "dist/main"]

+ 6 - 3
frameworks/TypeScript/nest/nestjs.dockerfile

@@ -1,10 +1,13 @@
-FROM node:12.3.1-slim
+FROM node:12.16.1-slim
 
 
 COPY ./ ./
 COPY ./ ./
 
 
-RUN yarn install
+RUN npm install
+RUN npm run build
 
 
 ENV NODE_ENV production
 ENV NODE_ENV production
 ENV DATABASE_CONFIGURATION_PROFILE=postgres
 ENV DATABASE_CONFIGURATION_PROFILE=postgres
+ENV FRAMEWORK=express
 
 
-CMD ["yarn", "start:prod"]
+EXPOSE 8080
+CMD ["node", "dist/main"]

+ 32 - 29
frameworks/TypeScript/nest/ormconfig.js

@@ -1,33 +1,36 @@
 let config = {
 let config = {
-    "synchronize":false,
-    "logging": false,
-    "entities": process.env.NODE_ENV === 'production' ? ["./dist/**/*.entity.js"] : ["./dist/**/*.entity.js", "./src/**/*.entity.ts"]
-}
+  synchronize: false,
+  logging: false,
+  entities:
+    process.env.NODE_ENV === 'production'
+      ? ['./dist/**/*.entity.js']
+      : ['./dist/**/*.entity.js', './src/**/*.entity.ts'],
+};
 
 
-switch(process.env.DATABASE_CONFIGURATION_PROFILE) {
-    case 'mysql':
-        config = {
-            ...config,
-            "type": "mysql",
-            "host": "tfb-database",
-            "port": 3306,
-            "username": "benchmarkdbuser",
-            "password": "benchmarkdbpass",
-            "database": "hello_world",
-        }
-        break;
-    case 'postgres':
-    default:
-        config = {
-            ...config,
-            "type": "postgres",
-            "host": "tfb-database",
-            "port": 5432,
-            "username": "benchmarkdbuser",
-            "password": "benchmarkdbpass",
-            "database": "hello_world",
-        }
-        break;
+switch (process.env.DATABASE_CONFIGURATION_PROFILE) {
+  case 'mysql':
+    config = {
+      ...config,
+      type: 'mysql',
+      host: 'tfb-database',
+      port: 3306,
+      username: 'benchmarkdbuser',
+      password: 'benchmarkdbpass',
+      database: 'hello_world',
+    };
+    break;
+  case 'postgres':
+  default:
+    config = {
+      ...config,
+      type: 'postgres',
+      host: 'tfb-database',
+      port: 5432,
+      username: 'benchmarkdbuser',
+      password: 'benchmarkdbpass',
+      database: 'hello_world',
+    };
+    break;
 }
 }
 
 
-module.exports = config
+module.exports = config;

+ 37 - 49
frameworks/TypeScript/nest/package.json

@@ -5,62 +5,50 @@
   "author": "",
   "author": "",
   "license": "MIT",
   "license": "MIT",
   "scripts": {
   "scripts": {
+    "prebuild": "rimraf dist",
+    "build": "nest build",
     "format": "prettier --write \"src/**/*.ts\"",
     "format": "prettier --write \"src/**/*.ts\"",
-    "start": "ts-node -r tsconfig-paths/register src/main.ts",
-    "start:dev": "nodemon",
-    "start:debug": "nodemon --config nodemon-debug.json",
-    "prestart:prod": "rm -rf dist && tsc && cp -r src/views/ dist/",
-    "start:prod": "node dist/main.js"
+    "start": "nest start",
+    "start:dev": "nest start --watch",
+    "start:debug": "nest start --debug --watch",
+    "start:prod": "node dist/main.js",
+    "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix"
   },
   },
   "dependencies": {
   "dependencies": {
-    "@nestjs/common": "6.6.7",
-    "@nestjs/core": "6.6.7",
-    "@nestjs/platform-express": "^6.0.0",
-    "@nestjs/typeorm": "6.1.3",
-    "dotenv": "8.1.0",
-    "express-cluster": "^0.0.5",
-    "fastify": "2.8.0",
+    "@nestjs/common": "6.11.8",
+    "@nestjs/core": "6.11.8",
+    "@nestjs/platform-express": "6.11.8",
+    "@nestjs/platform-fastify": "6.11.8",
+    "@nestjs/typeorm": "6.3.3",
+    "cache-manager": "3.0.0",
+    "dotenv": "8.2.0",
+    "fastify": "2.12.0",
     "fastify-formbody": "3.1.0",
     "fastify-formbody": "3.1.0",
-    "hbs": "^4.0.4",
-    "mysql2": "^1.7.0",
-    "pg": "7.12.1",
+    "hbs": "4.1.0",
+    "handlebars": "4.7.3",
+    "mysql2": "2.1.0",
+    "pg": "7.18.2",
+    "point-of-view": "3.7.1",
     "reflect-metadata": "0.1.13",
     "reflect-metadata": "0.1.13",
-    "rxjs": "6.5.3",
-    "typeorm": "0.2.19",
-    "typescript": "3.6.3"
+    "rimraf": "3.0.2",
+    "rxjs": "6.5.4",
+    "typeorm": "0.2.22"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@nestjs/testing": "6.6.7",
-    "@types/express": "4.17.1",
-    "@types/jest": "24.0.18",
-    "@types/node": "12.7.5",
-    "@types/supertest": "2.0.8",
-    "jest": "24.9.0",
-    "nodemon": "1.19.2",
-    "prettier": "1.18.2",
-    "rimraf": "3.0.0",
-    "supertest": "4.0.2",
-    "ts-jest": "24.1.0",
-    "ts-loader": "6.1.0",
-    "ts-node": "8.3.0",
+    "@nestjs/cli": "6.14.2",
+    "@nestjs/schematics": "6.9.4",
+    "@types/express": "4.17.2",
+    "@types/node": "13.7.4",
+    "@typescript-eslint/eslint-plugin": "2.20.0",
+    "@typescript-eslint/parser": "2.20.0",
+    "eslint": "6.8.0",
+    "eslint-config-prettier": "6.10.0",
+    "eslint-plugin-import": "2.20.1",
+    "nodemon": "2.0.2",
+    "prettier": "1.19.1",
+    "ts-loader": "6.2.1",
+    "ts-node": "8.6.2",
     "tsconfig-paths": "3.9.0",
     "tsconfig-paths": "3.9.0",
-    "tslint": "5.20.0",
-    "webpack": "4.40.2",
-    "webpack-cli": "3.3.8",
-    "webpack-node-externals": "1.7.2"
-  },
-  "jest": {
-    "moduleFileExtensions": [
-      "js",
-      "json",
-      "ts"
-    ],
-    "rootDir": "src",
-    "testRegex": ".spec.ts$",
-    "transform": {
-      "^.+\\.(t|j)s$": "ts-jest"
-    },
-    "coverageDirectory": "../coverage",
-    "testEnvironment": "node"
+    "typescript": "3.8.2"
   }
   }
 }
 }

+ 0 - 22
frameworks/TypeScript/nest/src/app.controller.spec.ts

@@ -1,22 +0,0 @@
-import { Test, TestingModule } from '@nestjs/testing';
-import { INestApplication } from '@nestjs/common';
-import { AppController } from './app.controller';
-import { AppService } from './app.service';
-
-describe('AppController', () => {
-  let app: TestingModule;
-
-  beforeAll(async () => {
-    app = await Test.createTestingModule({
-      controllers: [AppController],
-      providers: [AppService],
-    }).compile();
-  });
-
-  describe('root', () => {
-    it('should return "Hello World!"', () => {
-      const appController = app.get<AppController>(AppController);
-      expect(appController.root()).toBe('Hello World!');
-    });
-  });
-});

+ 53 - 5
frameworks/TypeScript/nest/src/app.controller.ts

@@ -1,13 +1,61 @@
-import { Get, Controller } from '@nestjs/common';
-
+import {
+  CacheInterceptor,
+  Controller,
+  Get,
+  Header,
+  Query,
+  Render,
+  UseInterceptors,
+} from '@nestjs/common';
 import { AppService } from './app.service';
 import { AppService } from './app.service';
 
 
 @Controller()
 @Controller()
 export class AppController {
 export class AppController {
   constructor(private readonly appService: AppService) {}
   constructor(private readonly appService: AppService) {}
 
 
-  @Get()
-  root(): string {
-    return this.appService.root();
+  @Get('/json')
+  @Header('Server', 'NestJS')
+  @Header('Content-Type', 'application/json')
+  getJson() {
+    return { message: 'Hello, World!' };
+  }
+
+  @Get('db')
+  @Header('Server', 'NestJS')
+  getSingleQuery() {
+    return this.appService.singleQuery();
+  }
+
+  @Get('queries')
+  @Header('Server', 'NestJS')
+  getMultiQueries(@Query('queries') queries) {
+    return this.appService.multiQueries(queries);
+  }
+
+  @Get('fortunes')
+  @Header('Server', 'NestJS')
+  @Render('fortunes.hbs')
+  getFortunes() {
+    return this.appService.fortunes();
+  }
+
+  @Get('updates')
+  @Header('Server', 'NestJS')
+  getUpdates(@Query('queries') queries) {
+    return this.appService.updates(queries);
+  }
+
+  @Get('plaintext')
+  @Header('Server', 'NestJS')
+  @Header('Content-Type', 'text/plain')
+  getHello(): string {
+    return 'Hello, World!';
+  }
+
+  @Get('/cached-worlds')
+  @Header('Server', 'NestJS')
+  @UseInterceptors(CacheInterceptor)
+  getCachedWorlds(@Query('count') count) {
+    return this.appService.cachedWorlds(count);
   }
   }
 }
 }

+ 8 - 5
frameworks/TypeScript/nest/src/app.module.ts

@@ -1,13 +1,16 @@
-import { Module } from '@nestjs/common';
+import { CacheModule, Module } from '@nestjs/common';
 import { TypeOrmModule } from '@nestjs/typeorm';
 import { TypeOrmModule } from '@nestjs/typeorm';
-
 import { AppController } from './app.controller';
 import { AppController } from './app.controller';
 import { AppService } from './app.service';
 import { AppService } from './app.service';
-import { BenchModule } from './bench/bench.module';
-
+import { Fortune } from './fortune.entity';
+import { World } from './world.entity';
 
 
 @Module({
 @Module({
-  imports: [TypeOrmModule.forRoot(), BenchModule],
+  imports: [
+    TypeOrmModule.forRoot(),
+    TypeOrmModule.forFeature([World, Fortune]),
+    CacheModule.register(),
+  ],
   controllers: [AppController],
   controllers: [AppController],
   providers: [AppService],
   providers: [AppService],
 })
 })

+ 68 - 2
frameworks/TypeScript/nest/src/app.service.ts

@@ -1,8 +1,74 @@
 import { Injectable } from '@nestjs/common';
 import { Injectable } from '@nestjs/common';
+import { InjectRepository } from '@nestjs/typeorm';
+import { Repository } from 'typeorm';
+import { Fortune } from './fortune.entity';
+import { World } from './world.entity';
 
 
 @Injectable()
 @Injectable()
 export class AppService {
 export class AppService {
-  root(): string {
-    return 'Hello World!';
+  constructor(
+    @InjectRepository(World)
+    private readonly worldRepository: Repository<World>,
+    @InjectRepository(Fortune)
+    private readonly fortuneRepository: Repository<Fortune>,
+  ) {}
+
+  singleQuery() {
+    const rand = Math.floor(Math.random() * 10000) + 1;
+    return this.worldRepository.findOne(rand);
+  }
+
+  async multiQueries(queries: string) {
+    const number = Math.min(Math.max(parseInt(queries) || 1, 1), 500);
+    const promisesArray = [];
+
+    for (let i = 0; i < number; i++) {
+      promisesArray.push(this.singleQuery());
+    }
+
+    const worlds = await Promise.all(promisesArray);
+    return worlds;
+  }
+
+  async fortunes() {
+    const allFortunes = await this.fortuneRepository.find();
+    allFortunes.push({
+      id: 0,
+      message: 'Additional fortune added at request time.',
+    });
+
+    allFortunes.sort((a, b) => (a.message < b.message ? -1 : 1));
+    return { fortunes: allFortunes };
+  }
+
+  async updates(queries) {
+    const number = Math.min(Math.max(parseInt(queries) || 1, 1), 500);
+    const worlds = [];
+    const promisesArray = [];
+
+    for (let i = 0; i < number; i++) {
+      const worldToUpdate = await this.singleQuery();
+      worldToUpdate.randomnumber = Math.floor(Math.random() * 10000) + 1;
+      worlds.push(worldToUpdate);
+      promisesArray.push(
+        this.worldRepository.update(worldToUpdate.id, {
+          randomnumber: worldToUpdate.randomnumber,
+        }),
+      );
+    }
+
+    await Promise.all(promisesArray);
+    return worlds;
+  }
+
+  async cachedWorlds(count) {
+    const number = Math.min(Math.max(parseInt(count) || 1, 1), 500);
+    const promisesArray = [];
+    for (let i = 0; i < number; i++) {
+      promisesArray.push(this.singleQuery());
+    }
+
+    const worlds = await Promise.all(promisesArray);
+    return worlds;
   }
   }
 }
 }

+ 0 - 15
frameworks/TypeScript/nest/src/bench/bench.controller.spec.ts

@@ -1,15 +0,0 @@
-import { Test, TestingModule } from '@nestjs/testing';
-import { BenchController } from './bench.controller';
-
-describe('Bench Controller', () => {
-  let module: TestingModule;
-  beforeAll(async () => {
-    module = await Test.createTestingModule({
-      controllers: [BenchController],
-    }).compile();
-  });
-  it('should be defined', () => {
-    const controller: BenchController = module.get<BenchController>(BenchController);
-    expect(controller).toBeDefined();
-  });
-});

+ 0 - 56
frameworks/TypeScript/nest/src/bench/bench.controller.ts

@@ -1,56 +0,0 @@
-import { Controller, Get, Header, Query, Res, Render } from '@nestjs/common';
-import { Response } from 'express';
-
-import { BenchService } from './bench.service';
-
-@Controller('bench')
-export class BenchController {
-    constructor(private benchService: BenchService){}
-
-    @Get('/db')
-    @Header('Server', 'NestJS')
-    getRandomWorld(){
-
-        return this.benchService.getOne();
-    }
-
-    @Get('/queries')
-    @Header('Server', 'NestJS')
-    getMultipleRandomWorlds(@Query('queries') query){
-
-        return this.benchService.getMultiple(query);
-    }
-
-    @Get('/updates')
-    @Header('Server', 'NestJS')
-    updateRandomWorlds(@Query('queries') query){
-
-        return this.benchService.updateMultiple(query);
-    }
-
-    @Get('/json')
-    @Header('Server', 'NestJS')
-    @Header('Content-Type', 'application/json')
-    sayHello() {
-
-        return JSON.stringify({message: 'Hello, World!'});
-    }
-
-    @Get('/plaintext')
-    @Header('Server', 'NestJS')
-    @Header('Content-Type', 'text/plain')
-    plaintext() {
-
-        return 'Hello, World!';
-    }
-
-    @Get('/fortunes')
-    @Render('fortunes')
-    @Header('Server', 'NestJS')
-    fortunes(@Res() res: Response) {
-        return this.benchService.getFortunes().then( fortunes => ({
-            fortunes,
-        }));
-    }
-
-}

+ 0 - 15
frameworks/TypeScript/nest/src/bench/bench.module.ts

@@ -1,15 +0,0 @@
-import { Module } from '@nestjs/common';
-import { TypeOrmModule } from '@nestjs/typeorm';
-
-import { BenchController } from './bench.controller';
-import { BenchService } from './bench.service';
-import { WorldEntity } from './../models/world.entity';
-import { FortuneEntity } from './../models/fortune.entity';
-
-@Module({
-  imports: [TypeOrmModule.forFeature([WorldEntity, FortuneEntity])],
-  controllers: [BenchController],
-  providers: [BenchService],
-  exports: [BenchService],
-})
-export class BenchModule {}

+ 0 - 15
frameworks/TypeScript/nest/src/bench/bench.service.spec.ts

@@ -1,15 +0,0 @@
-import { Test, TestingModule } from '@nestjs/testing';
-import { BenchService } from './bench.service';
-
-describe('BenchService', () => {
-  let service: BenchService;
-  beforeAll(async () => {
-    const module: TestingModule = await Test.createTestingModule({
-      providers: [BenchService],
-    }).compile();
-    service = module.get<BenchService>(BenchService);
-  });
-  it('should be defined', () => {
-    expect(service).toBeDefined();
-  });
-});

+ 0 - 66
frameworks/TypeScript/nest/src/bench/bench.service.ts

@@ -1,66 +0,0 @@
-import { Injectable } from '@nestjs/common';
-import { Repository } from 'typeorm';
-import { WorldEntity } from '../models/world.entity';
-import { FortuneEntity } from '../models/fortune.entity';
-import { InjectRepository } from '@nestjs/typeorm';
-
-@Injectable()
-export class BenchService {
-    constructor(
-        @InjectRepository(WorldEntity)
-        private worldRepository: Repository<WorldEntity>,
-        @InjectRepository(FortuneEntity)
-        private fortuneRepository: Repository<FortuneEntity>,
-    ){}
-
-    getOne(){
-
-        return this.worldRepository.findOne({ where: {id: Math.floor(Math.random() * 10000) + 1}});
-    }
-
-    async getMultiple(totalQueries: string) {
-
-        const worldArr = [];
-        const total = this.sanitizeQueries(totalQueries);
-        for (let i = 0; i < total; i++) {
-            worldArr.push(await this.getOne());
-        }
-        return worldArr;
-    }
-
-    async updateMultiple(totalQueries: string) {
-
-        const worldArr = [];
-        const total = this.sanitizeQueries(totalQueries);
-        for (let i = 0; i < total; i++) {
-            let worldToUpdate = await this.getOne();
-            worldToUpdate.randomnumber = Math.floor(Math.random() * 10000) + 1;
-            worldArr.push(worldToUpdate);
-            await this.worldRepository.update(worldToUpdate.id, worldToUpdate);
-        }
-        return worldArr;
-    }
-
-    async getFortunes(){
-        return this.fortuneRepository.find().then((fortunes) => {
-            const newFortune = { id: 0, message: "Additional fortune added at request time." };
-            fortunes.push(newFortune);
-            fortunes.sort((a, b) => (a.message < b.message) ? -1 : 1);
-            return fortunes;
-        });
-    }
-
-    sanitizeQueries(queries: string) {
-        const isNum = parseInt(queries, null);
-        if (isNum) {
-            if (isNum > 500) {
-                return 500;
-            } else if (isNum < 1) {
-                return 1;
-            }
-        } else {
-            return 1;
-        }
-        return isNum;
-    }
-}

+ 10 - 0
frameworks/TypeScript/nest/src/fortune.entity.ts

@@ -0,0 +1,10 @@
+import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
+
+@Entity('fortune')
+export class Fortune {
+  @PrimaryGeneratedColumn()
+  id: number;
+
+  @Column('text')
+  message: string;
+}

+ 55 - 14
frameworks/TypeScript/nest/src/main.ts

@@ -1,24 +1,65 @@
-import 'dotenv/config';
+import { Logger } from '@nestjs/common';
 import { NestFactory } from '@nestjs/core';
 import { NestFactory } from '@nestjs/core';
 import { NestExpressApplication } from '@nestjs/platform-express';
 import { NestExpressApplication } from '@nestjs/platform-express';
-import { AppModule } from './app.module';
+import {
+  FastifyAdapter,
+  NestFastifyApplication,
+} from '@nestjs/platform-fastify';
+import 'dotenv/config';
 import { join } from 'path';
 import { join } from 'path';
-import { Logger } from '@nestjs/common';
-import * as cluster from 'express-cluster';
-
+import { AppModule } from './app.module';
+import cluster = require('cluster');
+import os = require('os');
 
 
 const port = process.env.PORT || 8080;
 const port = process.env.PORT || 8080;
 
 
-async function bootstrap() {
-  await cluster(async (w)=>{
-    const app = await NestFactory.create<NestExpressApplication>(AppModule);
+async function bootstrapExpress() {
+  const app = await NestFactory.create<NestExpressApplication>(AppModule, {
+    logger: false,
+  });
+
+  app.setBaseViewsDir(join(__dirname, '..', 'views'));
+  app.setViewEngine('hbs');
 
 
-    app.setBaseViewsDir(join(__dirname, 'views'));
-    app.setViewEngine('hbs');
+  Logger.log(`Listening on port ${port}`, 'Nest Express Server');
+  return app.listen(port);
+}
 
 
-    Logger.log(`Listening on port ${port}`, 'Nest Server');
-    return  app.listen(port)
-  }, {});
+async function bootstrapFastify() {
+  const app = await NestFactory.create<NestFastifyApplication>(
+    AppModule,
+    new FastifyAdapter(),
+    { logger: false },
+  );
+  app.setViewEngine({
+    engine: {
+      handlebars: require('handlebars'),
+    },
+    templates: join(__dirname, '..', 'views'),
+  });
+  await app.listen(8080, '0.0.0.0');
 }
 }
 
 
-bootstrap();
+if (cluster.isMaster) {
+  const cpus = os.cpus().length;
+  for (let i = 0; i < cpus; i++) {
+    cluster.fork();
+  }
+
+  Logger.log('NestJS master starting ' + new Date().toISOString());
+  cluster.on('exit', () => {
+    process.exit(1);
+  });
+} else {
+  switch (process.env.FRAMEWORK) {
+    case 'fastify':
+      bootstrapFastify();
+      Logger.log(`Worker fastify ${process.pid} started`);
+      break;
+
+    default:
+      bootstrapExpress();
+      Logger.log(`Worker express ${process.pid} started`);
+      break;
+  }
+}

+ 0 - 10
frameworks/TypeScript/nest/src/models/fortune.entity.ts

@@ -1,10 +0,0 @@
-import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
-
-@Entity('fortune')
-export class FortuneEntity {
-    @PrimaryGeneratedColumn()
-    id: number;
-
-    @Column('text')
-    message: string;
-}

+ 0 - 10
frameworks/TypeScript/nest/src/models/world.entity.ts

@@ -1,10 +0,0 @@
-import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
-
-@Entity('world')
-export class WorldEntity {
-    @PrimaryGeneratedColumn()
-    id: number;
-
-    @Column('int')
-    randomnumber: number;
-}

+ 10 - 0
frameworks/TypeScript/nest/src/world.entity.ts

@@ -0,0 +1,10 @@
+import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
+
+@Entity('world')
+export class World {
+  @PrimaryGeneratedColumn()
+  id: number;
+
+  @Column()
+  randomnumber: number;
+}

+ 4 - 0
frameworks/TypeScript/nest/tsconfig.build.json

@@ -0,0 +1,4 @@
+{
+  "extends": "./tsconfig.json",
+  "exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
+}

+ 0 - 7
frameworks/TypeScript/nest/tsconfig.spec.json

@@ -1,7 +0,0 @@
-{
-  "extends": "tsconfig.json",
-  "compilerOptions": {
-    "types": ["jest", "node"]
-  },
-  "include": ["**/*.spec.ts", "**/*.d.ts"]
-}

+ 0 - 0
frameworks/TypeScript/nest/src/views/fortunes.hbs → frameworks/TypeScript/nest/views/fortunes.hbs