diff --git a/package.json b/package.json index 16f1e72..39edd03 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "@nestjs/config": "^4.0.2", "@nestjs/core": "^11.0.1", "@nestjs/platform-express": "^11.0.1", + "@nestjs/swagger": "^11.2.5", "reflect-metadata": "^0.2.2", "rxjs": "^7.8.1" }, diff --git a/src/core/app.controller.ts b/src/core/app.controller.ts index 0e6f930..39a6e34 100644 --- a/src/core/app.controller.ts +++ b/src/core/app.controller.ts @@ -1,16 +1,29 @@ import { Controller, Get } from '@nestjs/common' +import { ApiOkResponse, ApiOperation } from '@nestjs/swagger' import { AppService } from './app.service' +import { HealthResponseDto } from './dto' @Controller() export class AppController { constructor(private readonly appService: AppService) {} + @ApiOperation({ + summary: 'Welcome endpoint', + description: 'Return simple welcome message' + }) @Get() getHello() { return this.appService.getHello() } + @ApiOperation({ + summary: 'Healthcheck endpoint', + description: 'Check if gateway is running' + }) + @ApiOkResponse({ + type: HealthResponseDto + }) @Get('/health') healthCheck() { return this.appService.health() diff --git a/src/core/dto/index.ts b/src/core/dto/index.ts new file mode 100644 index 0000000..e7b548e --- /dev/null +++ b/src/core/dto/index.ts @@ -0,0 +1 @@ +export * from './rs' diff --git a/src/core/dto/rs/health.response.dto.ts b/src/core/dto/rs/health.response.dto.ts new file mode 100644 index 0000000..d962b47 --- /dev/null +++ b/src/core/dto/rs/health.response.dto.ts @@ -0,0 +1,17 @@ +import { ApiProperty } from '@nestjs/swagger' + +export class HealthResponseDto { + @ApiProperty({ + name: 'status', + description: 'Health status', + example: 'ok' + }) + public status: string + + @ApiProperty({ + name: 'timestamp', + description: 'Health timestamp', + example: '2022-01-01T00:00:00.000Z' + }) + public timestamp: string +} diff --git a/src/core/dto/rs/index.ts b/src/core/dto/rs/index.ts new file mode 100644 index 0000000..ecf8940 --- /dev/null +++ b/src/core/dto/rs/index.ts @@ -0,0 +1 @@ +export * from './health.response.dto' diff --git a/src/main.ts b/src/main.ts index bfc531b..e31cff1 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,6 +1,7 @@ import { Logger } from '@nestjs/common' import { ConfigService } from '@nestjs/config' import { NestFactory } from '@nestjs/core' +import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger' import { AppModule } from './core/app.module' @@ -15,6 +16,18 @@ async function bootstrap() { credentials: true }) + const swaggerConfig = new DocumentBuilder() + .setTitle('Teacinema API') + .setDescription('API Gateway for Teacinema microservices') + .setVersion('1.0.0') + .addBearerAuth() + .build() + + const swaggerDocument = SwaggerModule.createDocument(app, swaggerConfig) + SwaggerModule.setup('docs', app, swaggerDocument, { + yamlDocumentUrl: '/docs/openapi.yaml' + }) + const port = config.getOrThrow('HTTP_PORT') const host = config.getOrThrow('HTTP_HOST') diff --git a/yarn.lock b/yarn.lock index e9d4743..4fa934b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -934,6 +934,11 @@ resolved "https://registry.yarnpkg.com/@lukeed/csprng/-/csprng-1.1.0.tgz#1e3e4bd05c1cc7a0b2ddbd8a03f39f6e4b5e6cfe" integrity sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA== +"@microsoft/tsdoc@0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@microsoft/tsdoc/-/tsdoc-0.16.0.tgz#2249090633e04063176863a050c8f0808d2b6d2b" + integrity sha512-xgAyonlVVS+q7Vc7qLW0UrJU7rSFcETRWsqdXZtjzRU8dF+6CkozTK4V4y1LwOX7j8r/vHphjDeMeGI4tNGeGA== + "@napi-rs/wasm-runtime@^0.2.11": version "0.2.12" resolved "https://registry.yarnpkg.com/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz#3e78a8b96e6c33a6c517e1894efbd5385a7cb6f2" @@ -999,6 +1004,11 @@ path-to-regexp "8.3.0" tslib "2.8.1" +"@nestjs/mapped-types@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@nestjs/mapped-types/-/mapped-types-2.1.0.tgz#b9b536b7c3571567aa1d0223db8baa1a51505a19" + integrity sha512-W+n+rM69XsFdwORF11UqJahn4J3xi4g/ZEOlJNL6KoW5ygWSmBB2p0S2BZ4FQeS/NDH72e6xIcu35SfJnE8bXw== + "@nestjs/platform-express@^11.0.1": version "11.1.12" resolved "https://registry.yarnpkg.com/@nestjs/platform-express/-/platform-express-11.1.12.tgz#c9449230c3b8843370bca65d5b2c9909d3e3f0f6" @@ -1021,6 +1031,18 @@ jsonc-parser "3.3.1" pluralize "8.0.0" +"@nestjs/swagger@^11.2.5": + version "11.2.5" + resolved "https://registry.yarnpkg.com/@nestjs/swagger/-/swagger-11.2.5.tgz#41334fca6d42704e4175c04c15031046d73498e9" + integrity sha512-wCykbEybMqiYcvkyzPW4SbXKcwra9AGdajm0MvFgKR3W+gd1hfeKlo67g/s9QCRc/mqUU4KOE5Qtk7asMeFuiA== + dependencies: + "@microsoft/tsdoc" "0.16.0" + "@nestjs/mapped-types" "2.1.0" + js-yaml "4.1.1" + lodash "4.17.21" + path-to-regexp "8.3.0" + swagger-ui-dist "5.31.0" + "@nestjs/testing@^11.0.1": version "11.1.12" resolved "https://registry.yarnpkg.com/@nestjs/testing/-/testing-11.1.12.tgz#2edf74b5fde5591381e5155a4afb7bdb6f57fbce" @@ -1057,6 +1079,11 @@ resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.2.9.tgz#d229a7b7f9dac167a156992ef23c7f023653f53b" integrity sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA== +"@scarf/scarf@=1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@scarf/scarf/-/scarf-1.4.0.tgz#3bbb984085dbd6d982494538b523be1ce6562972" + integrity sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ== + "@sinclair/typebox@^0.34.0": version "0.34.47" resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.34.47.tgz#61b684d8a20d2890b9f1f7b0d4f76b4b39f5bc0d" @@ -3555,6 +3582,13 @@ js-tokens@^4.0.0: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== +js-yaml@4.1.1, js-yaml@^4.1.0, js-yaml@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.1.tgz#854c292467705b699476e1a2decc0c8a3458806b" + integrity sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA== + dependencies: + argparse "^2.0.1" + js-yaml@^3.13.1: version "3.14.2" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.2.tgz#77485ce1dd7f33c061fd1b16ecea23b55fcb04b0" @@ -3563,13 +3597,6 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" -js-yaml@^4.1.0, js-yaml@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.1.tgz#854c292467705b699476e1a2decc0c8a3458806b" - integrity sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA== - dependencies: - argparse "^2.0.1" - jsesc@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d" @@ -4607,6 +4634,13 @@ supports-color@^8.0.0, supports-color@^8.1.1: dependencies: has-flag "^4.0.0" +swagger-ui-dist@5.31.0: + version "5.31.0" + resolved "https://registry.yarnpkg.com/swagger-ui-dist/-/swagger-ui-dist-5.31.0.tgz#a2529f844c83b7e85c2caaf2c64a8277dd71db98" + integrity sha512-zSUTIck02fSga6rc0RZP3b7J7wgHXwLea8ZjgLA3Vgnb8QeOl3Wou2/j5QkzSGeoz6HusP/coYuJl33aQxQZpg== + dependencies: + "@scarf/scarf" "=1.4.0" + symbol-observable@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-4.0.0.tgz#5b425f192279e87f2f9b937ac8540d1984b39205"