Merged PR 4: API実装のためのディレクトリを構成

## 概要
[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を返却することを確認

## 補足
This commit is contained in:
斎藤 快斗 2023-02-20 08:12:36 +00:00
parent 0fa3b0eff8
commit 3b4b3c59e7
14 changed files with 132 additions and 42 deletions

View File

@ -7,7 +7,7 @@
"name": "Launch Program",
"runtimeExecutable": "npm",
"runtimeArgs": ["run", "start:debug"],
"envFile": "${workspaceFolder}/.env.local",
"envFile": "${workspaceFolder}/.env",
"console": "integratedTerminal"
}
]

View File

@ -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": {

View File

@ -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",

View File

@ -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<void> {
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();

View File

@ -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": {}
}
}

View File

@ -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) => ({

View File

@ -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>(AuthController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});

View File

@ -0,0 +1,4 @@
import { Controller } from '@nestjs/common';
@Controller('auth')
export class AuthController {}

View File

@ -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 {}

View File

@ -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>(AuthService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

View File

@ -0,0 +1,4 @@
import { Injectable } from '@nestjs/common';
@Injectable()
export class AuthService {}

View File

@ -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>(HealthController);
});
it('should be defined', () => {
expect(healthController).toBeDefined();
});
});

View File

@ -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();

View File

@ -34,7 +34,6 @@ services:
- network
volumes:
- ./cache:/data
networks:
network:
internal: false