From 3b4b3c59e77ed77c17e4ee38b7acd7dcd7093396 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=96=8E=E8=97=A4=20=E5=BF=AB=E6=96=97?= Date: Mon, 20 Feb 2023 08:12:36 +0000 Subject: [PATCH] =?UTF-8?q?Merged=20PR=204:=20API=E5=AE=9F=E8=A3=85?= =?UTF-8?q?=E3=81=AE=E3=81=9F=E3=82=81=E3=81=AE=E3=83=87=E3=82=A3=E3=83=AC?= =?UTF-8?q?=E3=82=AF=E3=83=88=E3=83=AA=E3=82=92=E6=A7=8B=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task: 1358](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/OMDSDictation/_sprints/taskboard/OMDSDictation%20%E3%83%81%E3%83%BC%E3%83%A0/OMDSDictation/%E3%82%B9%E3%83%97%E3%83%AA%E3%83%B3%E3%83%88%202_2?workitem=1358) - API実装を行うためのベースとなる実装を行いました。 - ディレクトリ構成 - ビルドの設定 - openapi.jsonの配置場所 - openapi.jsonの生成コマンド作成 ## レビューポイント - ベース実装として足りているか - openapi.jsonを生成するコードの配置場所は`src/api/generate.ts`で良いか ## UIの変更 - なし ## 動作確認状況 - ローカルで`/health`が200 OKを返却することを確認 ## 補足 --- dictation_server/.vscode/launch.json | 2 +- dictation_server/package-lock.json | 12 +++---- dictation_server/package.json | 1 + dictation_server/src/api/generate.ts | 31 +++++++++++++++++++ dictation_server/src/api/odms/openapi.json | 28 +++++++++++++++++ dictation_server/src/app.module.ts | 4 ++- .../src/features/auth/auth.controller.spec.ts | 18 +++++++++++ .../src/features/auth/auth.controller.ts | 4 +++ .../src/features/auth/auth.module.ts | 9 ++++++ .../src/features/auth/auth.service.spec.ts | 18 +++++++++++ .../src/features/auth/auth.service.ts | 4 +++ .../src/health.controller.spec.ts | 19 ------------ dictation_server/src/main.ts | 23 ++++++-------- docker-compose.yml | 1 - 14 files changed, 132 insertions(+), 42 deletions(-) create mode 100644 dictation_server/src/api/generate.ts create mode 100644 dictation_server/src/api/odms/openapi.json create mode 100644 dictation_server/src/features/auth/auth.controller.spec.ts create mode 100644 dictation_server/src/features/auth/auth.controller.ts create mode 100644 dictation_server/src/features/auth/auth.module.ts create mode 100644 dictation_server/src/features/auth/auth.service.spec.ts create mode 100644 dictation_server/src/features/auth/auth.service.ts delete mode 100644 dictation_server/src/health.controller.spec.ts diff --git a/dictation_server/.vscode/launch.json b/dictation_server/.vscode/launch.json index 6ccdb32..051c76a 100644 --- a/dictation_server/.vscode/launch.json +++ b/dictation_server/.vscode/launch.json @@ -7,7 +7,7 @@ "name": "Launch Program", "runtimeExecutable": "npm", "runtimeArgs": ["run", "start:debug"], - "envFile": "${workspaceFolder}/.env.local", + "envFile": "${workspaceFolder}/.env", "console": "integratedTerminal" } ] diff --git a/dictation_server/package-lock.json b/dictation_server/package-lock.json index de08d2f..5808b82 100644 --- a/dictation_server/package-lock.json +++ b/dictation_server/package-lock.json @@ -4113,9 +4113,9 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "node_modules/cookiejar": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", - "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", "dev": true }, "node_modules/core-util-is": { @@ -13550,9 +13550,9 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "cookiejar": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", - "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", "dev": true }, "core-util-is": { diff --git a/dictation_server/package.json b/dictation_server/package.json index 792c5a3..42bf69a 100644 --- a/dictation_server/package.json +++ b/dictation_server/package.json @@ -8,6 +8,7 @@ "scripts": { "prebuild": "rimraf dist", "build": "nest build", + "apigen:odms": "ts-node src/api/generate.ts", "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", "start": "nest start", "start:dev": "nest start --watch", diff --git a/dictation_server/src/api/generate.ts b/dictation_server/src/api/generate.ts new file mode 100644 index 0000000..3ab6410 --- /dev/null +++ b/dictation_server/src/api/generate.ts @@ -0,0 +1,31 @@ +import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger'; +import { Test } from '@nestjs/testing'; +import { AppModule } from '../app.module'; +import { promises as fs } from 'fs'; +async function bootstrap(): Promise { + const controllers = Reflect.getMetadata('controllers', AppModule); + const providers = Reflect.getMetadata('providers', AppModule); + const mockedProviders = providers.map((provider) => { + return { + provide: provider.name, + useValue: {}, + }; + }); + + const testingModule = await Test.createTestingModule({ + controllers: controllers, + providers: mockedProviders, + }).compile(); + const app = await testingModule.createNestApplication(); + + const options = new DocumentBuilder() + .setTitle('ODMSOpenAPI') + .setVersion('1.0.0') + .build(); + const document = SwaggerModule.createDocument(app, options); + await fs.writeFile( + 'src/api/odms/openapi.json', + JSON.stringify(document, null, 2), + ); +} +bootstrap(); diff --git a/dictation_server/src/api/odms/openapi.json b/dictation_server/src/api/odms/openapi.json new file mode 100644 index 0000000..d5c8e55 --- /dev/null +++ b/dictation_server/src/api/odms/openapi.json @@ -0,0 +1,28 @@ +{ + "openapi": "3.0.0", + "paths": { + "/health": { + "get": { + "operationId": "checkHealth", + "summary": "", + "parameters": [], + "responses": { + "200": { + "description": "" + } + } + } + } + }, + "info": { + "title": "OMDSOpenAPI", + "description": "", + "version": "1.0.0", + "contact": {} + }, + "tags": [], + "servers": [], + "components": { + "schemas": {} + } +} \ No newline at end of file diff --git a/dictation_server/src/app.module.ts b/dictation_server/src/app.module.ts index cf9bcf0..4fea7f6 100644 --- a/dictation_server/src/app.module.ts +++ b/dictation_server/src/app.module.ts @@ -5,16 +5,18 @@ import { ConfigModule, ConfigService } from '@nestjs/config'; import { join } from 'path'; import { TypeOrmModule } from '@nestjs/typeorm'; import { LoggerMiddleware } from './common/loggerMiddleware'; +import { AuthModule } from './features/auth/auth.module'; @Module({ imports: [ ServeStaticModule.forRoot({ - rootPath: join(__dirname, '..', 'build'), + rootPath: join(__dirname, '../../dictation_client', 'build'), }), ConfigModule.forRoot({ envFilePath: ['.env.local', '.env'], isGlobal: true, }), + AuthModule, // TypeOrmModule.forRootAsync({ // imports: [ConfigModule], // useFactory: async (configService: ConfigService) => ({ diff --git a/dictation_server/src/features/auth/auth.controller.spec.ts b/dictation_server/src/features/auth/auth.controller.spec.ts new file mode 100644 index 0000000..27a31e6 --- /dev/null +++ b/dictation_server/src/features/auth/auth.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { AuthController } from './auth.controller'; + +describe('AuthController', () => { + let controller: AuthController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [AuthController], + }).compile(); + + controller = module.get(AuthController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/dictation_server/src/features/auth/auth.controller.ts b/dictation_server/src/features/auth/auth.controller.ts new file mode 100644 index 0000000..268eeb2 --- /dev/null +++ b/dictation_server/src/features/auth/auth.controller.ts @@ -0,0 +1,4 @@ +import { Controller } from '@nestjs/common'; + +@Controller('auth') +export class AuthController {} diff --git a/dictation_server/src/features/auth/auth.module.ts b/dictation_server/src/features/auth/auth.module.ts new file mode 100644 index 0000000..a7d9fbc --- /dev/null +++ b/dictation_server/src/features/auth/auth.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; +import { AuthController } from './auth.controller'; +import { AuthService } from './auth.service'; + +@Module({ + controllers: [AuthController], + providers: [AuthService], +}) +export class AuthModule {} diff --git a/dictation_server/src/features/auth/auth.service.spec.ts b/dictation_server/src/features/auth/auth.service.spec.ts new file mode 100644 index 0000000..800ab66 --- /dev/null +++ b/dictation_server/src/features/auth/auth.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { AuthService } from './auth.service'; + +describe('AuthService', () => { + let service: AuthService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [AuthService], + }).compile(); + + service = module.get(AuthService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/dictation_server/src/features/auth/auth.service.ts b/dictation_server/src/features/auth/auth.service.ts new file mode 100644 index 0000000..a41c649 --- /dev/null +++ b/dictation_server/src/features/auth/auth.service.ts @@ -0,0 +1,4 @@ +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class AuthService {} diff --git a/dictation_server/src/health.controller.spec.ts b/dictation_server/src/health.controller.spec.ts deleted file mode 100644 index 19be6e8..0000000 --- a/dictation_server/src/health.controller.spec.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { HealthController } from './health.controller'; - -describe('HealthController', () => { - let healthController: HealthController; - - beforeEach(async () => { - const app: TestingModule = await Test.createTestingModule({ - controllers: [HealthController], - providers: [], - }).compile(); - - healthController = app.get(HealthController); - }); - - it('should be defined', () => { - expect(healthController).toBeDefined(); - }); -}); diff --git a/dictation_server/src/main.ts b/dictation_server/src/main.ts index 1c1914c..9a2faeb 100644 --- a/dictation_server/src/main.ts +++ b/dictation_server/src/main.ts @@ -14,20 +14,15 @@ async function bootstrap() { // バリデーター(+型の自動変換機能)を適用 app.useGlobalPipes(new ValidationPipe({ transform: true })); - /*TODO SwaggerUIでの表示はローカルのみにする - 下の参考ページのような感じで対応する予定 - https://tech.mobilefactory.jp/entry/2019/12/18/180000 - */ + if (process.env.STAGE === 'local') { + const options = new DocumentBuilder() + .setTitle('ODMSOpenAPI') + .setVersion('1.0.0') + .build(); + const document = SwaggerModule.createDocument(app, options); + SwaggerModule.setup('api', app, document); + } - const options = new DocumentBuilder() - .setTitle('OMDSOpenAPI') - .setVersion('1.0.0') - .build(); - const document = SwaggerModule.createDocument(app, options); - SwaggerModule.setup('api', app, document); - - // TODO:検証のためポートを固定 後で直す - // await app.listen(process.env.PORT || 80); - await app.listen(80); + await app.listen(process.env.PORT || 80); } bootstrap(); diff --git a/docker-compose.yml b/docker-compose.yml index b49cc3a..d5d246a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -34,7 +34,6 @@ services: - network volumes: - ./cache:/data - networks: network: internal: false