From db417675057fb7389c7e8fc675b466d7f7fb43fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B5=9C=EC=A4=80=ED=9D=A0?= Date: Wed, 31 Aug 2022 17:10:31 +0900 Subject: [PATCH] =?UTF-8?q?NestJS=20=EC=88=98=EC=A0=951..?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 3 ++- src/main.ts | 18 +++++++--------- src/prisma.service.ts | 17 ++++++++++++++- src/todo/todo.controller.ts | 43 +++++++++++++++++++++++++++++++------ src/todo/todo.service.ts | 15 +++++++------ 5 files changed, 70 insertions(+), 26 deletions(-) diff --git a/.env b/.env index 2f6bd20..49fa4ae 100644 --- a/.env +++ b/.env @@ -5,7 +5,8 @@ # See the documentation for all the connection string options: https://pris.ly/d/connection-strings DATABASE_URL="mysql://root:@localhost:3306/test" -CORS_ALLOW_LIST = ['http://localhost:8080'] +CORS_ALLOW_ORIGINS = ['http://localhost:8080'] +CORS_ALLOW_METHOD = "GET,PUT,POST,DELETE,PATCH,OPTIONS" JWT_SECURITY_KEY = "security_key" JWT_EXPIRE_MAX = "600s" diff --git a/src/main.ts b/src/main.ts index cae1d04..6db46ea 100644 --- a/src/main.ts +++ b/src/main.ts @@ -3,17 +3,15 @@ import { HttpException, HttpStatus } from '@nestjs/common' import { NestFactory } from '@nestjs/core' import { AppModule } from './app.module' -import { logger } from './logger.middleware' async function bootstrap() { + const app = await NestFactory.create(AppModule) //Enable All CORS Requests : https://docs.nestjs.com/security/cors - const corsOptions = { + app.enableCors({ origin: (origin, callback) => { //origin URL이 허용된 경우 또는 orgin자체가 없는 경우(postman tool) 통과 - if (process.env.CORS_ALLOW_LIST.includes(origin) || !origin) { - console.log( - 'Allowed Origin URL: ' + !origin ? 'JSON tool 사용' : origin - ) + if (process.env.CORS_ALLOW_ORIGINS.indexOf(origin) !== -1 || !origin) { + console.log('Allowed Origin URL: ' + origin) callback(null, true) } else { callback( @@ -26,10 +24,10 @@ async function bootstrap() { ) ) } - } - } - const app = await NestFactory.create(AppModule) - app.enableCors({ ...corsOptions }) + }, + methods: process.env.CORS_ALLOW_METHOD, + credentials: true + }) //app.use(logger) await app.listen(3000, function () { console.log( diff --git a/src/prisma.service.ts b/src/prisma.service.ts index 4a215a9..a79c4fe 100644 --- a/src/prisma.service.ts +++ b/src/prisma.service.ts @@ -3,12 +3,27 @@ import { PrismaClient } from '@prisma/client' @Injectable() export class PrismaService extends PrismaClient implements OnModuleInit { + constructor() { + //SQL 로그를 출력하기위해 추가 + super({ + log: [ + { emit: 'event', level: 'query' }, + { emit: 'stdout', level: 'info' }, + { emit: 'stdout', level: 'warn' }, + { emit: 'stdout', level: 'error' } + ], + errorFormat: 'colorless' + }) + } + async onModuleInit() { await this.$connect() } async enableShutdownHooks(app: INestApplication) { - this.$on('beforeExit', async () => { + this.$on('beforeExit', async (event) => { + //SQL 로그를 출력하기위해 추가 + console.log(event.name) await app.close() }) } diff --git a/src/todo/todo.controller.ts b/src/todo/todo.controller.ts index 569abec..8bb1347 100644 --- a/src/todo/todo.controller.ts +++ b/src/todo/todo.controller.ts @@ -26,18 +26,42 @@ export class TodoController { console.log(query) //Field별 filter AND Sql용 - const filterSql = {} + let filterSql = {} + switch (query.filterField) { + case 'is_done': + if (query.filter) { + filterSql = { + AND: { + [query.filterField]: query.filter + } + } + } + break + case 'updatedAt': + case 'createdAt': + if (query.filterDateStart && query.filterDateEnd) { + filterSql = { + AND: { + [query.filterField]: { + gte: new Date(query.filterDateStart) as Date, + lte: new Date(query.filterDateEnd) as Date + } + } + } + } + break + } console.log(filterSql) //Field별 search OR Sql용 let searchSql = {} if (query.search) { - const searchFieldSQL = [] + const searchFieldSQLs = [] for (const index in query.searchFields) { switch (query.searchFields[index]) { case 'title': case 'content': - searchFieldSQL.push({ + searchFieldSQLs.push({ [query.searchFields[index]]: { contains: query.search as string } @@ -45,19 +69,23 @@ export class TodoController { break case 'updatedAt': case 'createdAt': - searchFieldSQL.push({ + searchFieldSQLs.push({ [query.searchFields[index]]: { gte: new Date(query.search) as Date } }) break } - console.log(searchFieldSQL) } - searchSql = { OR: searchFieldSQL } - console.log(searchSql) + console.log(searchFieldSQLs) + searchSql = { OR: searchFieldSQLs } } + console.log(searchSql) + //Field별 Sort Sql용 + if (!query.sortBy) { + query.sortBy = 'id' + } const orderBySql = { [query.sortBy]: query.sortDesc === 'true' ? 'desc' : 'asc' } @@ -70,6 +98,7 @@ export class TodoController { const perPage = query.perPage ? parseInt(query.perPage) : parseInt(process.env.DEFAULT_TABLE_PERPAGE) + const fetchSQL = { skip: page * perPage, take: perPage, diff --git a/src/todo/todo.service.ts b/src/todo/todo.service.ts index cb9ec98..be4113f 100644 --- a/src/todo/todo.service.ts +++ b/src/todo/todo.service.ts @@ -4,22 +4,23 @@ import { PrismaService } from 'src/prisma.service' @Injectable() export class TodoService { - constructor(private prisma: PrismaService) {} + constructor(private prisma: PrismaService) { + prisma.$on('query', (event: Prisma.QueryEvent) => { + console.log('Query: ' + event.query) + console.log('Duration: ' + event.duration + 'ms') + }) + } //참고: https://intrepidgeeks.com/tutorial/05-instagram-clone-code-5-user-summary //전체조회 async count(params: { - skip?: number - take?: number cursor?: Prisma.TodoWhereUniqueInput where?: Prisma.TodoWhereInput - orderBy?: Prisma.TodoOrderByWithRelationInput }): Promise { - const { skip, take, cursor, where, orderBy } = params + const { cursor, where } = params return this.prisma.todo.count({ cursor, - where, - orderBy + where }) }