프로젝트에서 사용하는 기술 스택/라이브러리와, 선정한 이유
사용 프레임워크: NestJS
프로젝트에서는 런타임 오류를 방지하고 코드 가독성을 높이기 위해 TypeScript를 선택하였습니다. 이에 따라 TypeScript에 기반한 NestJS를 프레임워크로 사용하였습니다.
NestJS는 Express.js와 같은 기능을 제공하면서도 추가적인 기능들을 제공하여 효율적인 개발이 가능해집니다. 또한, 모듈 기반의 아키텍처로 재사용성을 늘리고, 의존성 주입(Dependency Injection), IoC, AOP와 같은 객체지향 개념을 도입하여 신뢰성 있는 소프트웨어를 보다 쉽게 작성할 수 있게 됩니다.
또한 Express.js를 사용 시 필요한 라이브러리를 찾는 시간이 오래 걸리는 문제와, 과도한 유연함에서 오는 SW의 품질 저하 등을 줄이고자 저희 팀은 TypeScript를 개발 언어로 NestJS를 프레임워크로 사용하여 효율적인 개발과 유지 보수성을 높이기로 결정하였습니다.
MySQL
저희 서비스에서 사용되는 자료들인 카테고리, 상품, 주문 내역 등은 각 정보간의 상관관계를 이용해야 더 쉽게 자료를 찾고 사용할 수 있기 때문에 NoSQL이 아닌 RDB를 선택했습니다.
RDB 중에서는 MySQL을 선택한 이유는 이미 경험해보았고, 구글링을 통해 정보를 쉽게 얻을 수 있을 것이라는 장점이 있기 때문입니다. 또한, MySQL은 오픈 소스 데이터베이스 관리 시스템 중에서 가장 많이 사용되어서 많은 사용자 커뮤니티가 있어서 정보를 얻기 쉽다는 장점도 있습니다. 이러한 이유들로 인해 저희 프로젝트에서는 MySQL을 선택하게 되었습니다.
TypeORM
프로젝트에서는 RDB를 선택하였으며, NestJS에서 많이 사용되는 RDBMS 중 Prisma와 TypeORM 중에서 고민을 하였습니다. 하지만, 팀전체가 Prisma를 배운 적이 없고,
이미 경험이 있는 TypeORM을 더 공부하고자 하여 TypeORM을 선택하게 되었습니다.
TypeORM은 TypeScript로 작성되어 있어 타입 안정성이 높으며, ORM(Object-Relational Mapping)으로 관계형 데이터베이스와 상호작용을 할 수 있도록 도와줍니다.
또한, 쿼리 작성을 편리하게 해주고, 강력한 마이그레이션 기능을 제공하여 db 스키마를 관리할 수 있습니다. 또한, Active Record 패턴과 Data Mapper 패턴 모두를 지원하여 개발자들이 자유롭게 선택할 수 있도록 합니다. 이러한 장점들이 TypeORM을 선택한 이유입니다.
Docker
팀원 간 컴퓨터 운영체제와 **Node, MySQL** 버전이 다름으로 인한 코드의 동작 오류를 방지하기 위해서 같은 개발 환경을 만들기 위해서 사용했습니다.
Redis 이번 프로젝트에서는 중요하지만 DB에 저장하기에는 적절하지 않은 정보들을 서버에 저장하면, 서버가 다운되거나 재시작될 때 데이터가 유실될 수 있으므로 Redis를 사용하여 메모리 기반의 데이터 저장소를 만들어서 보다 안전하고 빠르게 데이터를 저장하였습니다.
예를 들어, Refresh Token과 같은 인증 정보는 Redis에 저장하여 서버 다운 시에도 데이터를 보존할 수 있습니다. Redis는 또한 높은 성능을 제공하여 많은 양의 데이터를 빠르게 처리할 수 있으므로, 이번 프로젝트에서는 Refresh Token과 같은 인증 정보와 같은 빈번하게 접근되는 데이터를 Redis를 사용하여 안전하고 빠르게 데이터를 저장하기로 결정하였습니다
EJS - 지금까지 공부해온 렌더 라이브러리여서 바로 적용이 가능해서 선택했습니다.
라이브러리 (종속성)
//Nest.js의 기본 라이브러리
"@nestjs-modules/mailer": "^1.8.1",
메일 전송을 위한 라이브러리
"@nestjs/axios": "^2.0.0",
SMS 문자 인증을 위한 라이브러리
"@nestjs/common": "^9.0.0",
decorator가 정의되어있는 라이브러리
"@nestjs/config": "^2.3.1",
.env를 DI로 받아와 사용하기 위한 라이브러리
"@nestjs/core": "^9.0.0",
NestFactory가 정의되어 있는 라이브러리
"@nestjs/jwt": "^10.0.2",
jwt token / decode / verify 등의 메서드가 정의되어 있는 라이브러리
"@nestjs/passport": "^9.0.3",
Jwt 전략에 대한 정보가 정의되어있는 라이브러리
"@nestjs/platform-express": "^9.0.0",
main.ts / NestExpressApplication가 정의되어 있는 라이브러리
"@nestjs/typeorm": "^9.0.1",
TypeORM을 사용하기 위해 설치해야 할 라이브러리
"@nestjs/swagger": "^6.2.1",
추후 API 관리를 위한 (프로젝트 완성 후 사용해보려고 깔아두었음) 라이브러리
"@nestjs/terminus": "^9.2.1",
서버 Health-check을 위한 라이브러리
"typeorm": "^0.3.12",
typeORM 사용을 위한 라입러리
"axios": "^1.3.4",
문자 전송 서비스를 구현하기 위해 설치 해두었음
"bcrypt": "^5.1.0",
비밀번호 암호화 및 복호화를 위해 설치
//Redis 관련 라이브러리
"cache-manager": "^4.0.0",
"cache-manager-redis-store": "^2.0.0",
"redis": "^3.1.2",
Redis 사용을 위해 설치 하였음
//입력값 검증 라이브러리
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
Decorator를 통한 Object의 Property 검증을 위해 설치
"cli": "^1.0.1",
Node.js의 라이브러리 중 하나 인것 같음 (잘 모르겠습니다)
"cookie-parser": "^1.4.6",
쿠키 내용을 확인하기 위해 설치 main.ts에서 전역으로 사용중
"ejs": "^3.1.8",
템플릿 엔진 사용을 위해 설치
"joi": "^17.8.3",
현재는 .env에 빠진 값들 유효성 검사만 진행중
"mysql2": "^3.1.2",
mysql2를 누군가 쓰려고 설치해둔 것 같은데 현재는 쓰지 않고 있는걸 발견
//winston 관련 라이브러리
"nest-winston": "^1.9.0",
"winston": "^3.8.2"
Custom Logger 기능을 위한 라이브러리 (현재는 주석처리되어 사용하지 않고 있음)
"nodemailer": "^6.9.1",
메일 발송을 위한 Nodemailer
//passport 관련 라이브러리
"passport": "^0.6.0",
"passport-google-oauth20": "^2.0.0",
"passport-jwt": "^4.0.1",
"passport-kakao": "^1.0.1",
"passport-local": "^1.0.0",
"passport-naver": "^1.0.6",
passport 전략과 OAuth 로그인 기능을 쉽게 사용하기 위해 설치한 라이브러리
"reflect-metadata": "^0.1.13",
데이터의 데이터[메타데이터?]를 조금 더 쉽게 활용 할 수 있는 라이브러리
설치는 되어있으나 사용하지 않고있는 라이브러리
"rxjs": "^7.2.0",
Logger에서 사용중이며, 이벤트 처리를 쉽게 하기 위해서 설치하는 라이브러리로 알고있음
라이브러리 (개발 종속성)
//Nest.js 기본 라이브러리
"@nestjs/cli": "^9.0.0",
"@nestjs/schematics": "^9.0.0",
"@nestjs/testing": "^9.0.0",
nest-cli 설치시 자동으로 설치되는 라이브러리로 알고 있음
//@types 라이브러리
"@types/bcrypt": "^5.0.0",
"@types/express": "^4.17.13",
"@types/jest": "29.2.4",
"@types/node": "18.11.18",
"@types/passport-jwt": "^3.0.8",
"@types/passport-local": "^1.0.35",
"@types/supertest": "^2.0.11",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
TypeScript에 관한 Types들을 정의해놓은 라이브러리?
//eslint 라이브러리
"eslint": "^8.0.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
줄맞춤, 자간, 간격등을 정해놓은 양식에 맞추지 않으면 빨간 글씨를 띄워주는 개발자의 좋은 친구
//Test 관련 라이브러리
"supertest": "^6.1.3",
"jest": "29.3.1",
테스트코드 작성을 위한 라이브러리
"prettier": "^2.3.2",
줄맞춤, 자간, 간격등을 정해놓은 양식으로 맞춰주는 개발자의 좋은 친구
"source-map-support": "^0.5.20",
런타임의 오류스택에 .ts 매핑 정보를 띄워주는 라이브러리
//TypeScript 관련 라이브러리
"ts-jest": "29.0.3",
"ts-loader": "^9.2.3",
"ts-node": "^10.9.1",
"tsconfig-paths": "4.1.1",
"typescript": "^4.7.4"
타입스크립트 환경에서 개발을 할 수 있게 도와주는 라이브러리들
숙제: 멘토링 결과 다음 주까지 해올 일
팀 전체 (리더와 부리더님께서 필두로 정리해 주세요.)
팀원 개인별로 작성해 주세요.
우태현 :
조봉진 :
이한결, 성민섭 :
이혜원:
이외에도 기술적인 방향을 잡기 위한 질문을 정리해두시면 가장 좋습니다!
→ 단, “A는 어떻게 구현하나요”의 질문은 삼가주세요.
→ “A와 B를 알아보았는데, 둘 중 A가 낫다고 판단했는데 맞을까요?”의 식의 고민의 흔적을 담아 질문해주세요.
조봉진: 이미지를 업로드-임시 폴더를 생성하여 저장- 게시글과 함께 submit (이 과정중에
포스트맨으로 만들면 어려우니 html페이지 생성-완료)- 이미지를 지정된 경로에 저장 후
변경된 경로를 db에 저장하라는 솔루션을 받았습니다
첫번째로는 새로운 서비스 코드가 늘고, 코드가 너무 의미없이 길어지는 것 같습니다
간결한 코드가 가능한지 궁금합니다
두번째는 목록에도 대표 이미지를 보여줘야 할 텐데 필드를 추가해야 할지 (main:true
이런식으로 구현해야 할지) 고민이 됩니다