-
Notifications
You must be signed in to change notification settings - Fork 2
1주차 개인 회고
- 근거있는 선택 하고 기록하기
- 왜 이 기술을 사용하려고 하는지, 다른 기술은 없는지 학습하고 기록하기
- 코드 한 줄을 짜더라도 생각하고 더 나은 방향은 없는지 고민하기
- 학습할 때 글 하나만 보고 대충 정리하지 말고 여러 자료를 참고해서 깊이 학습하기
- 기초 다지기
- NestJS 깊이 파보기
- 데이터베이스 정규화, 트랜잭션, 쿼리 최적화 등 학습 및 정리, 구현
- 서버 구조 고민하기
- NGINX 학습 및 적용 계획 세우기
- NCP 서비스들 학습 및 전략 세우기
- docker, GitHub Action 학습 및 적용 계획 세우기
1주차에는 백엔드의 기술적 고민은 어떤 것이 있을까? 라는 고민을 많이 했습니다.
프로젝트 기획을 고려했을 때 단순 CRUD 기능만 구현하다가 끝나는 것이 아닌가? 다른 새로운 기술을 적용해야하나? 라는 생각이 많이 들었습니다.
같은 백엔드 팀원인 재하님과도 이런 얘기를 나누고 비슷한 고민을 했습니다.
그러던 중 저희 팀 백엔드 멘토님 근수님이 좋은 말씀을 많이 해주셔서 마음이 조금 편해졌습니다.
근수님께서는 백엔드 신입의 이력서에 새롭고 화려한 기술들이 많아도 사실 기대치가 별로 높지 않다, 차라리 이 사람이 코드 짠 것을 보고 구조나 객체지향적 설계 등을 더 확인하는 편이다 라는 말씀을 해주셨습니다.
또한 기술을 억지로 사용하려고 하기 보다는 자연스러운 흐름으로 이 기술을 사용해야 하는 이유를 설명할 수 있는 것이 좋다고 말씀을 해주셨습니다.
그래서 어느 정도 방향성을 잡을 수 있었습니다.
새로운 기술적 도전을 부담스럽게 받아들이지 말고, 기초에 충실해서 NestJS 코드 구조부터 잘 설계하고, 데이터베이스 관련 지식을 학습하고 정리해보자! 라는 생각을 했습니다.
그리고 기술을 선택할 때 조금 더 고민하고, 다른 기술과의 차이점 등을 고려하여 선정 과정을 기록하는 것도 괜찮겠다는 생각을 했습니다.
이렇게 꾸준히 할 것을 잘 해낸다면 6주를 허무하게 보냈다는 생각은 들지 않을 것이라고 느껴졌습니다.
프로젝트 설정 중 패키지 매니저를 저희 팀은 Yarn Berry를 사용하자고 정했습니다.
그러나 비교적 최신 기술이고, 자료도 그렇게 많지 않아서 설정 과정에서 조금 어려움이 있었습니다.
팀원들과 시간을 투자해서 함께 고민한 결과 잘 해결할 수 있었습니다.
트러블슈팅 과정
아직 기획 단계만 거쳐서 특별한 트러블 슈팅은 따로 없었습니다.
- NoSQL을 사용하는 이유에 대해서 확실하게 정리하지 않으면 나중에 혹시 면접 같은 곳에서 공격을 받을 수도 있을 것 같다는 말씀을 해주셨음
- PostgreSQL에서도 좌표 관련해서 지원을 해주는 타입이 있다고 어디서 들은 것 같으시다고 알아보시는것을 추천을 해주셨음
- TDD를 할 계획을 세우신 것이 좋다는 말씀을 해주셨음
- 금주는 팀원들과 함께 기획 및 문서작성 등을 진행하였습니다. 아이디어 주제를 확정하고 레포지토리에 위키를 만들어 프로젝트 소개, 백로그, 컨벤션등을 채워 넣는등의 작업들을 진행했습니다.
- 또한 컴포넌트 트리 작성, 폴더 구조 확정 및 화면 설계, DB 테이블 설계 등 프로젝트 진행을 위해 필요한 설계도 진행하였습니다.
- 팀원분들과의 시너지가 잘 맞아 오프라인으로 자주 만나고 오래 작업하였음에도 전혀 지치거나 힘들지 않아 너무 좋았습니다. 함께하는 팀원분들이 다들 배려심이 많으시고 적극적으로 활동해주셔서 같이 일할 때 힘이나는것 같습니다.
- 확실히 온라인으로 진행하는 것보다 오프라인으로 만나서 하는 것이 의사결정도 빠르고, 분업하기도 좋다는 생각이 들었습니다. 최대한 팀원분들을 자주 만나뵐 수 있으면 좋겠습니다. 다들 멀지 않은 곳에 거주하고 있어 정말 다행입니다!
- 많은 것들을 배우고 정리했지만, 이번 주 동안 가장 많이 집중하고 학습하게 된 것은 Yarn berry 관련 내용들인 것 같습니다. 처음 Yarn berry를 알게되고 적용해보려고 하면서 마음처럼 쉽게 설정되지 않았는데, 문제를 해결하기 위해 정말 많은 것들을 시도해보고 검색해보면서 자연스럽게 Yarn berry의 동작 방식이나, 폴더 구조에 대해 깊게 이해할 수 있게 된 것 같습니다. 차후에 다른 곳에서 Yarn berry를 사용하게 되더라도 이제는 정말 빠르게 적용하고 사용할 수 있을 것 같은 자신감이 생겼습니다.
- 추가로 학습정리를 하면서 번들러에 대해서도 자세하게 학습할 기회가 생겨 많은 부분들에 대해 궁금점을 해소할 수 있었습니다. 학습한 내용들을 블로그에 잘 정리해두어야겠습니다.
- 금주동안 세운 계획들과 설계에 맞추어 다음주부터는 실제 구현에 돌입할 예정입니다. 금일부터 해서 주말까지 이번 주 동안 학습한 내용들을 휘발되지 않게 잘 정리하고, 휴식과 함께 컨디션 관리하면서 월요일 부터 다시 몰입할 수 있도록 잘 정비해야겠습니다.
- 해야할 일이 너무 많아보여 우선순위를 잘 정해서 시간관리를 잘 해야할 것 같다는 의견을 주셨습니다.
이번주는 KPT 회고 방법론을 적용하여 회고를 해보았다.
이번주 나의 목표는 두 가지였다.
첫 번째, 무언가를 결정할 때 항상 ‘왜’를 생각하기.
이번주는 팀원들과 프로젝트의 기본적인 것들을 함께 정하는 시간을 가졌다. 나의 이번 프로젝트 목표 중 가장 중요한 것은 무엇이든 ‘왜’를 생각하며 하는 것이었다. 그래서 이번 주에 함께 결정하는 것들에 대해 이유를 찾아보고 이해하고 싶었다. 그 중 가장 중요한 것이 ‘기술스택 선정 이유’이라고 생각한다.
이번에 프론트엔드 팀원들과 함께 모여 여러 기술들을 찾아보며, 나름의 타당한 근거를 가진 기술들을 쓰기로 결정하였다. 그리고 각자 기술 1-2개씩 맡아 해당 기술 선택 이유에 대해 자세히 적어보기로 했다. 나는 zustand 선택 이유를 기술블로그로 작성했다. 지금까지는 상태관리 라이브러리를 선택할 때 ‘꼭 그것을 써야 하는 이유’에 대해 생각해본 적이 없었다. 그냥 요즘 이 라이브러리가 뜬다고 하니까, 팀원이 이 라이브러리를 쓰자고 하니까…와 같은 이유만으로 해당 라이브러리를 사용해왔다. 이번에는 다른 라이브러리들과 비교하여 왜 이 라이브러리를 사용해야 하는지 고민하고 기록으로 남겨둘 수 있게 되었다. 이런 과정을 경험해보고 있다는 것 자체로도 이전의 프로젝트에 비해 많이 성장함을 느낀다.
두 번째, 결정 과정들을 기록으로 남겨두기.
최근 이력서를 써보며 많이 아쉬웠던 점이 있다. 바로 프로젝트를 하며 기록을 많이 남기지 못한 것이었다. 분명 그 때는 정말 열심히 한 것 같은데, 이제와서 생각해보면 기억나는 것이 별로 없다… 그때 왜 그런 결정을 내렸는지, 왜 그렇게 코드를 짰는지 거의 생각이 나지 않았다. 그래서 이번에는 과정 하나하나 모두 기록으로 남겨두고 싶었다.
이번 주는 팀원들과 모여 이야기한 내용들을 최대한 회의록에 작성하려 했고, 프로젝트 세팅 과정이나 그 과정에서 발생한 트러블 슈팅을 기록으로 남겨두었다. 이렇게 꾸준히 기록을 남긴다면 그것만으로도 성공한 프로젝트라고 할 수 있을 것 같다.
팀원들과 의견을 맞추는 부분에서 어려움이 있었던 것 같다. 우리 팀 사람들은 모두 긍정적이고 여유로운 반면, 나는 항상 불안해하며 초조해하는 편이다. 또 다들 의견을 강하게 제시하는 편이 아닌데, 나는 상대적으로 주장하는 바가 명확한 편이다. ‘내 의견이 정말로 아닌 것 같으면 누군가 강하게 제지하지 않을까?’라는 생각에 내 주장을 너무 내세운 것 같다는 생각이 들었다. 특히 모두가 괜찮다고 하는데 나 혼자 불편해하는 부분에 대해서 너무 신경썼던 것 같다. 다들 성향이 다르니 의견 차이가 발생하는 건 어쩔 수 없을 것이다. 하지만 팀원 대부분의 의견이 내 의견과 반대된다면 타당한 근거를 들어 팀원들을 설득하거나, 내 의견을 굽히는 것이 맞다. 이번 주에 눈에 띄는 갈등이 발생하지는 않았지만, 되돌아보면 팀원들이 나를 많이 배려해준게 아닌가 싶은 생각이 든다.
사실 나의 타고난 성격이 하루아침에 고쳐지지는 않겠지만… 모두를 설득할 수 있을 만한 타당한 근거 없이 내 의견을 주장하는 것은 자제하려 한다. ‘내가 지금 생각한 의견이 팀원 모두에게 도움이 되는 것일까?’를 항상 생각하고 말해보자.
개인적으로 너무 서두르지 않은 것이 가장 잘했다고 생각한다. 팀원도 5명이고 구현하고자 하는 내용도 다들 잘 알지 못하는 내용이다 보니 계속 어떤 것을 구현할지, 구현할 수 있을지에 대한 생각이 바뀌었다. 그렇다 보니 너무 서두르게 개발을 시작했다면 중간에 계속 방향이 바뀌지 않았을까 싶다. 다행히 우리는 모든 준비를 마무리하고 개발을 시작하기로 했고 그에 맞게 준비하는데 많은 시간을 썼다. 6주 과정인 만큼 서두르기 보다는 천천히 체계적으로 하는게 더 좋을 것 같다.
준비에 많은 시간을 쓴 만큼 가능한 자세한 기능까지 생각해 놓으려 했다. 이건 큰 문제가 아니었는데 중요도가 낮거나 나중에 구현할 기능들까지 자세히 생각해 놓으려 했다. 부수적인 기능들인 만큼 각자의 생각에서 특히 더 큰 차이를 보이는 내용들이었는데 이것들을 정리하는데 필요 이상의 노력을 들인것 같다. 나중에 할 일은 너무 정교화 하기 보다는 대략적인 방향성 정도 잡아놓는게 좋지 않을까 싶다.
준비를 잘 해 놓을 수록 이후의 과정에서 더 편하게 진행할 수 있는만큼 가능한 많이 준비해 놓는것이 좋기는 할 것 같다. 하지만 너무 나중의 내용까지 준비하는게 그리 효율적인것 같지는 않다. 차라리 나중에 한번 더 회의를 하고 방향을 잡는게 좋지 않을까 싶다. 그래도 가능한 자세하게 계획을 세우는 것은 좋은것 같다. 우리 계획대로 매주 월요일 마다 그 주 계획을 세우는 방식은 유지 하면서 틈틈히 방향성에 관한 논의를 하면 좋지 않을까 싶다.
첫주부터 참 다사다난했습니다 ㅋ ㅋ 기획도 계속 변경되고, 간단할거라 생각했던 프로젝트 세팅부터 아주아주 많은 난관에 부딪혀 우당탕탕 그 잡채 !
그렇지만 그룹원들과 거의 매일같이 만나 머리를 맞대고 있으니 어떻게든 해결이 되는 기적을 여러 번 경험했습니다. 아직도 해결해나가야 할 일이 많지만, 이 멤버들과 함께라면 그 무엇도 두렵지가 않네요. 남은 5주도 ㅍㅇㅌㅍㅇㅌ 💥 💥 !
- 배포
- GitHub Actions와 Docker를 활용한 CI/CD
- AWS, NCP
- 아키텍처 구조
- 각 인스턴스들의 역할 : EC2(Server), Lambda(Cloud Functions), S3(Object Storage), VPC(VPC), ELB(Load Balancer), RDS(CloudDB) 등
- NGINX
- HTTPS(SSL/TLS) 구축하기
- 로드 밸런싱 기능 활용
- 보안 기능(IP/Port 스캐닝 차단 등) 활용
- 리버스 프록시를 통해 프론트엔드, 백엔드, 스토리지 서버 등 요청 처리
- DB
- MySQL 동시성 제어
- 쿼리 최적화
- NestJS
- NestJS LifeCycle
- Test
- TDD로 개발하기
- 부하 테스트 및 로드 밸런싱을 통한 대용량 트래픽 대비
-
클라우드 Infra 관리
와CI/CD
에 초점을 둔 학습과 성장을 해보자! -
DB 쿼리 최적화
와트랜잭션 관리(동시성 제어)
에 관해 학습과 성장을 해보자! -
NestJS
와Test(TDD, 부하 테스트)
에 관해 학습과 성장을 해보자!
Naver Cloud Platform에서 제공하는 AI Servies
기술스택 선정이유 (NestJS, TypeORM, Docker, GitHub Actions)
(아래 내용과 종합하여 별도 포스팅을 작성할 예정입니다)
// user.entity.ts
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column({ type: 'varchar', length: 50, nullable: false, unique: true })
username: string;
@Column({ type: 'varchar', length: 100, nullable: false })
password: string;
@Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })
created_at: Date;
@Column({ type: 'varchar', length: 50, nullable: false, unique: true })
nickname: string;
@Column({ type: 'json', nullable: false })
galaxy_style: string;
}
// board.entity.ts
import {
Column,
CreateDateColumn,
Entity,
Point,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';
@Entity()
export class Board {
@PrimaryGeneratedColumn()
id: number;
@Column({ type: 'varchar', length: 255, nullable: false })
title: string;
@Column({ type: 'text', nullable: true })
content: string;
@Column({ type: 'blob', nullable: true })
image: Buffer;
@Column({ type: 'json', nullable: false })
star_style: string;
@Column({ type: 'point', nullable: false })
star_position: Point;
@Column({ type: 'varchar', length: 50, nullable: false })
author: string;
@CreateDateColumn()
created_at: Date;
@UpdateDateColumn()
modified_at: Date;
}
- AWS, NCP로 배포
- 각 인스턴스 서비스들의 역할 및 인스턴스 구성 방법 고민
- 인스턴스 생성 및 관리 실습
- NGINX 기능 정리, 활용 방안 고민
- 리버스 프록시, 로드 밸런싱, IP/Port 스캐닝 차단, HTTPS(SSL/TLS)
- HTTPS 구현 방법 고민
- 부하 테스트와 로드 밸런싱 방법 고민
- NestJS TDD 구현 방식 정리
- Controller, Service 테스트 코드 작성 방식 결정
- Transaction을 활용한 DB CRUD 테스트
- Code Coverage 고려
- NestJS
- Middleware 및 Enhancer(Guard, Interceptor, Exception Filter) 개념 정리 및 활용 방안 고민
- 이미지 파일 저장 (리사이징, 확장자 통일, 스토리지 서버 저장)
- DB
- MySQL 동시성 제어
- 쿼리 최적화 (+ 정규화, 인덱싱)
- POINT, JSON 등 다양한 데이터 타입의 활용
- MongoDB(NoSQL) 활용 방안
Q. AWS, NCP의 인스턴스에 접근할 때 외부 IP를 설정해야 원격 접속을 할 수 있는데, BE/FE/NGINX 각각을 인스턴스로 배포하게 되면, docker image를 pull할 때 BE/FE는 어떻게 원격으로 접속하실건지? 외부 IP 3개를 사용하실 건지?
A. 이 부분을 답변 못해서 외부 IP를 여러개 사용할 지 고민했었는데, 2가지 방법이 있겠습니다.
- NGINX는 어짜피 외부IP 연결이 필요하므로 특정 포트를 포트포워딩 시켜서 BE/FE SSH 연결을 허용하는 방식
- docker 이미지로만 구분하고 세 컨테이너를 1개의 NCP Server 인스턴스에 한 번에 배포하는 방식
작은 프로젝트이고, 크레딧도 한정되어 있으므로 지금은 잠정적으로 2번 방식을 생각하고 있습니다. docker 네트워크 설정해서 SSH 포트만 다른 걸로 포트포워딩해주고, 비번관리 잘하면 될 것 같네요.
- 프론트엔드 Task와 관계 없이 백엔드 Task를 확보하기 위한 몇 가지 제안을 받았습니다.
- 관리자 페이지 구현
- Mock 데이터 크롤러 개발하여 자동 DB 연동
© 2023 debussysanjang
- 🐙 [가은] Three.js와의 설레는 첫만남
- 🐙 [가은] JS로 자전과 공전을 구현할 수 있다고?
- ⚽️ [준섭] NestJS 강의 정리본
- 🐧 [동민] R3F Material 간단 정리
- 👾 [재하] 만들면서 배우는 NestJS 기초
- 👾 [재하] GitHub Actions을 이용한 자동 배포
- ⚽️ [준섭] 테스트 코드 작성 이유
- ⚽️ [준섭] TypeScript의 type? interface?
- 🐙 [가은] 우리 팀이 Zustand를 쓰는 이유
- 👾 [재하] NestJS, TDD로 개발하기
- 👾 [재하] AWS와 NCP의 주요 서비스
- 🐰 [백범] Emotion 선택시 고려사항
- 🐧 [동민] Yarn berry로 모노레포 구성하기
- 🐧 [동민] Vite, 왜 쓰는거지?
- ⚽️ [준섭] 동시성 제어
- 👾 [재하] NestJS에 Swagger 적용하기
- 🐙 [가은] 너와의 추억을 우주의 별로 띄울게
- 🐧 [동민] React로 멋진 3D 은하 만들기(feat. R3F)
- ⚽️ [준섭] NGINX 설정
- 👾 [재하] Transaction (트랜잭션)
- 👾 [재하] SSH 보안: Key Forwarding, Tunneling, 포트 변경
- ⚽️ [준섭] MySQL의 검색 - LIKE, FULLTEXT SEARCH(전문검색)
- 👾 [재하] Kubernetes 기초(minikube), docker image 최적화(멀티스테이징)
- 👾 [재하] NestJS, 유닛 테스트 각종 mocking, e2e 테스트 폼데이터 및 파일첨부
- 2주차(화) - git, monorepo, yarn berry, TDD
- 2주차(수) - TDD, e2e 테스트
- 2주차(목) - git merge, TDD
- 2주차(일) - NCP 배포환경 구성, MySQL, nginx, docker, docker-compose
- 3주차(화) - Redis, Multer 파일 업로드, Validation
- 3주차(수) - AES 암복호화, TypeORM Entity Relation
- 3주차(목) - NCP Object Storage, HTTPS, GitHub Actions
- 3주차(토) - Sharp(이미지 최적화)
- 3주차(일) - MongoDB
- 4주차(화) - 플랫폼 종속성 문제 해결(Sharp), 쿼리 최적화
- 4주차(수) - 코드 개선, 트랜잭션 제어
- 4주차(목) - 트랜잭션 제어
- 4주차(일) - docker 이미지 최적화
- 5주차(화) - 어드민 페이지(전체 글, 시스템 정보)
- 5주차(목) - 감정분석 API, e2e 테스트
- 5주차(토) - 유닛 테스트(+ mocking), e2e 테스트(+ 파일 첨부)
- 6주차(화) - ERD
- 2주차(화) - auth, board 모듈 생성 및 테스트 코드 환경 설정
- 2주차(목) - Board, Auth 테스트 코드 작성 및 API 완성
- 3주차(월) - Redis 연결 후 RedisRepository 작성
- 3주차(화) - SignUpUserDto에 ClassValidator 적용
- 3주차(화) - SignIn시 RefreshToken 발급 및 Redis에 저장
- 3주차(화) - 커스텀 AuthGuard 작성
- 3주차(수) - SignOut시 토큰 제거
- 3주차(수) - 깃헙 로그인 구현
- 3주차(토) - OAuth 코드 통합 및 재사용
- 4주차(수) - NestJS + TypeORM으로 MySQL 전문검색 구현
- 4주차(목) - NestJS Interceptor와 로거
- [전체] 10/12(목)
- [전체] 10/15(일)
- [전체] 10/30(월)
- [FE] 11/01(수)~11/03(금)
- [전체] 11/06(월)
- [전체] 11/07(화)
- [전체] 11/09(목)
- [전체] 11/11(토)
- [전체] 11/13(월)
- [BE] 11/14(화)
- [BE] 11/15(수)
- [FE] 11/16(목)
- [FE] 11/19(일)
- [BE] 11/19(일)
- [FE] 11/20(월)
- [BE] 11/20(월)
- [BE] 11/27(월)
- [FE] 12/04(월)
- [BE] 12/04(월)
- [FE] 12/09(금)
- [전체] 12/10(일)
- [FE] 12/11(월)
- [전체] 12/11(월)
- [전체] 12/12(화)