본 게시글은 Prography 7기 6팀 백엔드 팀원으로 참여하여 Pilit 서비스를 개발한 과정과 소개를 담고 있습니다.
Introduce
Pilit은 바쁜 현대 사회를 살고있는 사람들을 위해 영양제 조합을 추천하고, 영양제를 놓이지 않고 먹을 수 있도록 돕는 서비스 입니다.
Role
Backend Engineer & Devops Engineer
Architecture
AWS Service | Amazon Elastic Container Service ( Fargate ) |
Amazon Elastic Container Registry | |
Amazon Elastic Load Balancer | |
Amazon ElastiCache ( Redis ) | |
Amazon Relational Database Service ( Mysql ) | |
Amazon Route 53 | |
Deployment Pipeline | Github Actions |
Web Framework | Nest.js |
TypeORM | |
BullMQ ( https://docs.bullmq.io/ ) | |
Messaging Solution | Firebase Cloud Messaging |
Feature
- 복용하는 약을 조회/생성/갱신/제거 할 수 있는 API 구현
- 일자별 복용여부를 확인하는 API 구현
- 복용 시점이 다가왔을 때 Client에게 Notification을 제공
Experience for Nest.js
- 기능별 모듈화 & MVC 패턴
- 기능별로 모듈을 생성하여 각각의 모듈은 맡은 기능의 책임을 다하도록 구현
- 다른 모듈의 변화가 일어나도 결합도를 낮춰서 최대한 의존성이 없도록 구현
- 필요시 Dependency Injection을 통해 공유할 수 있도록 구현
- 모듈 내부에 MVC 패턴을 사용하여 각각의 기능별로 컨트롤러가 존재하도록 구현
- MVC 패턴을 모듈화와 함께 적용하여 가독성, 확장성, 재사용성을 증가
- 기능별로 모듈을 생성하여 각각의 모듈은 맡은 기능의 책임을 다하도록 구현
- RESTful API & 직관적인 Naming
- 모듈명, 함수명 그리고 변수명의 Naming을 직관적으로 작성
- 모듈명과 함수명만 봐도 어떠한 기능을 하는지 최대한 이해할 수 있도록 작성
- 모듈별로 기능을 분리해 놓았기에 직관적으로 작성 가능
- RESTful API 규칙을 최대한 활용하여 작성
- API만 보고 어떤 기능을 하는지 직관적으로 이해할 수 있도록 작성
- 방법, 버전, 행위 그리고 명사형을 API가 길어지더라도 작성
- 예를들어, GET api/v1/pill/taking-log API를 직관적으로 파악 가능
- 버전1이며 약의 복용 기록을 가져오는 API
- 모듈명, 함수명 그리고 변수명의 Naming을 직관적으로 작성
- BullMQ & Firebase Cloud Messaging
- BullMQ는 Message Queue를 Node.js 위에서 쉽게 사용할 수 있도록 하는 라이브러리
- Redis를 기반이며 BullMQ에 Redis관련 Configuration 정보만 입력하면 쉽게 활용 가능
- BullMQ를 통해 Job을 Managing하여 Nest.js 상에서 Job을 관리
- Cron Job 형태를 제공하여 Message Queue가 특정 시점에 실행 될 수 있도록 구현 가능
- 사용자가 복용시간 등록시 Cron 형태로 변환하여 Job을 등록 할 수 있도록 구현
- Firebase Cloud Messaging은 구글에서 제공하는 Cross-platform messaging solution
- Client의 Platform( Android & IOS )과 상관 없이 쉽게 연동할 수 있어서 선정
- 모바일의 Online 상태와 Background 상태일때 모두 작동할 수 있도록 구현
- BullMQ에 Job을 등록할때 Job 내부에 Message push 코드를 삽입하여 특정 시간에 Notification이 가도록 구현
- BullMQ는 Message Queue를 Node.js 위에서 쉽게 사용할 수 있도록 하는 라이브러리
- JWT
- JWT 토큰의 사용방식에 대한 이해
- Access Token & Refresh Token 사용 방식에 대해 이해하고 Nest.js에서 특정 API에 대해 Authentication 과정을 진행할 수 있도록 구현
- 본 프로젝트에서는 빠른 MVP 모델 개발을 위해 ID & PW 방식을 도입하지 않고 모바일 기기별로 갖고 있는 UUID를 고객 식별용으로 사용
- JWT의 Expire 시간을 짧게 가져가서 MVP 모델 개발을 위해 사용하지 않은 Refresh Token 방식을 대체하기 위해 노력
Experience for AWS
- Amazon Elastic Container Service
- AWS ECS는 AWS에서 제공하는 Container Orchestration 서비스
- AWS EC2 대신 Fargate 방식을 활용하여 AWS ECS를 생성
- 총 3개의 Container를 띄워놓고 Load Balancer를 통해 부하 분산
- 기본적으로 롤링 배포를 사용하도록 설정
- AWS ECR의 Container Image를 불러와서 AWS ECS 상에 Container로 실행
- Amazon Elastic Container Registry ( AWS ECR )
- AWS ECR은 AWS에서 제공하는 Container Registry 서비스
- Github Actions을 통해 Docker로 Build된 이미지를 전달 받으며 Private Repository에 저장되도록 설정
- Amazon Elastic Load Balancer
- AWS ELB는 AWS에서 제공하는 Load Balancer
- 고가용성을 지원하는 AWS ECS를 사용하기 위해서는 AWS ELB가 최소 1개이상 꼭 필요
- Health Check용 API를 미리 구현해 놓고 Load Balancer가 해당 API에 주기적으로 요청
- 응답하는 Status Code를 기준으로 사전에 설정해놓은 Healthy Code가 응답하면 Container가 띄워져 있는 것으로 판단하며 그외 응답코드가 반환되면 Container가 죽은 것으로 판단
- 해당 작업을 잘못 설정하여 오류가 발생했던 내용을 정리 ( https://linho.kr/3 )
- Amazon Relational Database Service
- AWS RDS는 AWS에서 Fully Managed로 제공하는 데이터베이스 서비스
- MySQL Database로 생성하여 Nest.js의 TypeORM과 연결하여 사용
- ERD를 그려서 TypeORM에 엔티티를 생성하고 관련해서 Data Transfer Object를 만들어서 Swagger에 연동하거나 Validation을 진행하고 모듈간의 결합도를 낮추기 위한 용도로 사용
- Amazon ElastiCache
- AWS ElastiCache는 AWS에서 Fully Managed로 Redis를 제공하는 서비스
- Redis는 BullMQ에서 Message Queue를 사용하기 위해
- Amazon Route 53
- AWS Route 53은 AWS에서 DNS 설정용 서비스
- prograpy에서 제공한 DNS 서비스를 활용하기 위해 사용
- AWS Route53에 등록되어있던 Prograpy 인증서를 함께 지원하여 본 API를 https 방식으로 서비스 제공
- 결과적으로 https://api.prography.org/api/v1/pill/taking-log 형태의 API를 Client에게 제공
Experience for Github Actions
- Github Actions Workflow 파일
- .github/workflow 에서 yml 파일로 Deploy Pipeline을 구축
- Docker를 활용하여 Github Actions 내부에서 Build 하는 과정을 수행
- AWS IAM에서 제공하는 Access Token과 Secret Access Key를 발급 받아 Credentials 진행
- AWS CLI를 사용하여 스크립트를 작성
- Github Actions Secret Key
- Github Actions 내부에서 사용되는 보안 정보를 암호화 하기 위한 방법
- Deploy Pipeline 툴 특성상 배포에 사용되는 민감한 정보들이 담길 수 밖에 없는데 이를 Github Actions Secret Key를 사용하여 처리
- .env 파일 생성
- Nest.js의 보안 정보는 .env에서 관리하여 수동으로 .env파일을 생성
- Github Actions에서 리눅스 명령어를 제공하여 Github Actions Secret Key와 조합하여 .env파일을 생성
Improvement
- API Response시
- API Response시 날 것의 JSON을 보내는 방식이 아닌 한번 감싸서 값을 보낸다고 한다.
- 간략하게 예를 들면 {"name":"이재준","age":26} 이 아닌 {"data":["name":"이재준","age":26]} 처럼 data로 값을 감싼다.
- IAM 방식
- AccessToken 방식을 사용하는 것도 보안상 위험할 수 있지만, 해당 토큰에 많은 권한을 한번에 몰아주는 것 또한 위험하다.
- 지식이 많이 부족한 상태에서 한개의 토큰에 많은 권한을 제공하였는데 필요에 맞게 권한을 분배해서 토큰이 유출되었을 경우에도 보안성을 크게 훼손하지 않도록 해야한다.
- JWT 사용방식
- Logout 방법 구현과 Refresh Token을 사용하지 못한 점이 아쉬웠다. 해당 부분 Redis를 사용하여 Token을 Black 하거나 Refresh Token을 사용하여 주기적으로 토큰을 갱신할 수 있도록 개선해 나간다.
Github
'Project' 카테고리의 다른 글
[한이음 2022] MSA기반 인사 관리 시스템 Popool (0) | 2023.06.04 |
---|---|
[Dynamic Designer Developer DDD] 오모지 (0) | 2023.06.04 |
[ 졸업프로젝트 캡스톤 디자인 ] Seear (0) | 2023.06.04 |