https://github.com/to1step/backend
ํ์๋ค์ด ๊ฐ์์ ๋ก์ปฌ์์ ๊ฐ๋ฐ์ ํ์๊ธฐ ๋๋ฌธ์, ๊ฐ์ ๋ฐ์คํฌํฑ์ node.js
๋ฒ์ ์ด ๋ฌ๋ผ ๋ฐ์ํ๋ ์๋ฌ๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด nvm
์ ํตํด node.js
์ ๋ฒ์ ์ 16์ผ๋ก ์ผ์น์์ผฐ์ต๋๋ค.
โ๏ธ nvm์ ์ด์ฉํ node.js ๋ฒ์ ๊ด๋ฆฌ
REST์ ์์น์ ์ง์ผ ๊ฐ๊ฒฐํ๊ณ ๊ฐ๋ ์ฑ์ด ์ข์ API๋ฅผ ์ค๊ณํ์๊ณ , UI์ ๋ฌถ์ด์ง ์๋ API๋ฅผ ์ค๊ณํ์ฌ API์ ํ์ฅ์ฑ์ ๋์์ต๋๋ค.
โ๏ธ REST API๋? | โ๏ธ REST ์์น์ ์งํค๋ฉฐ API๋ฅผ ์ค๊ณํ์ | โ๏ธ API๋ UI์ ์ข ์๋์ง ์์์ผ ํ๋ค
Node.js๋ ์์ ๋๊ฐ ๋งค์ฐ ๋๊ธฐ ๋๋ฌธ์, Controller๋ Service๊ฐ ๋ฐ๋ก ๋ถ๋ฆฌ๋์ด ์์ง ์์์ต๋๋ค. ์ด์ MVC ํจํด์ ์ ์ฉํ์ฌ Controller์ Service ๋ถ๋ฆฌํ๊ณ ์ดํ๋ฆฌ์ผ์ด์ ์ ์ ์ง๋ณด์์ฑ, ํ์ฅ์ฑ, ์ฝ๋ ์ฌ์ฌ์ฉ์ฑ์ ํฅ์์์ผฐ์ต๋๋ค.
โ๏ธ MVC ํจํด์ด๋?
class-validator
๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์๋ก๋ถํฐ ์
๋ ฅ๋ฐ์ ๋ฐ์ดํฐ๋ ์ธ๋ถ์์ ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ ๊ฒ์ฆํ์ฌ ์๋ชป๋ ๋ฐ์ดํฐ๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ค์ด๊ฐ๋ ๊ฒ์ ๋ฐฉ์งํ์์ต๋๋ค.
๊ฐ๋ฐ ๋จ๊ณ์์๋ง ์ฌ์ฉ๋๊ณ , ์ค์ ํ๋ก๋์
ํ๊ฒฝ์์๋ ํ์ํ์ง ์์ ํจํค์ง๋ค์ devDependenc
๋ก ๋ณ๋ ๋ถ๋ฆฌํ์ฌ ์ค์นํ์ฌ ํ๋ก๋์
๋น๋ ์์ ๋ ๊ฐ๋ณ๊ณ ํจ์จ์ ์ธ ๋น๋๋ฅผ ํ ์ ์๊ฒ ํ์์ต๋๋ค.
์ ํฌ์ ํด๋ผ์ฐ๋ ์๋ฒ๊ฐ ํ๊ตญ์ ์กด์ฌํ์ง ์๊ธฐ ๋๋ฌธ์, ๋ชจ๋ ์๊ฐ์ ํ๊ตญ ์๊ฐ์ผ๋ก ํต์ผํด ์ฃผ๊ธฐ์ํด ๋ ์ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋์ ํ์ฌ์ผ ํ๋๋ฐ, ๊ทธ ์ค ํฌ๊ธฐ๊ฐ ์๊ณ ๊ฐ๋ฒผ์ ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉ๋๋ day.js๋ฅผ ์ฑํํ์์ต๋๋ค.
์๋ฒ์์ ๋ฐ์ํ ์ ์๋ ์๋ฌ๋ฅผ BadRequestError
, UnauthorizedError
, ForbiddenError
, InternalServerError
, NotFoundError
๋ก ๋๋์ด classํ ํ๊ณ Front-end๊ฐ ์ฒ๋ฆฌํ ์ ์๋ ์๋ฌ๋ค์ ๋ํด์ ErrorCode๋ค์ ๋ฏธ๋ฆฌ enum type์ผ๋ก ์ ์ํด ๋ ๋ค์, ํด๋น ์๋ฌ์ ๋ง๋ class๋ก mappingํ์ฌ Front-end์ ์ํตํ์์ต๋๋ค.
โ๏ธ Custom Error๋ฅผ ์ด์ฉํ Front-end์์ ์ํต
Winston.js
๋ฅผ ์ด์ฉํ์ฌ ์๋ฒ์ ๋ค์ด์ค๋ ๋ชจ๋ ์์ฒญ, ์๋ฒ์์ ๋ฐ์ํ๋ ๋ชจ๋ ์๋ฌ์ ๋ํด ํ์ผ๋ก ๊ธฐ๋กํ์์ต๋๋ค.
โ๏ธ Winston.js๋ฅผ ํตํ ๋ก๊ทธ ๊ธฐ๋กํ๊ธฐ
์๋ฒ์์ ๋ฐ์ํ๋ Exception Error์ ๋ํด Discord.js
๋ฅผ ํตํด Discord๋ก ๋ฉ์ธ์ง๋ฅผ ๋ณด๋ด๊ฒ ํ์ฌ ๋ฐ๋ก ๋์ํ ์ ์๋๋ก ํ์๊ณ , API์์์๊ฐ์ ๊ณ์ฐํ์ฌ 2000ms ์ด์ ๊ฑธ๋ฆฌ๋ API์ ๋ํด์ Discord๋ก ๋ฉ์ธ์ง๋ฅผ ๋ณด๋ด ๋ก์ง์ ๊ฐ์ ํ ์ ์๊ฒ ํ์์ต๋๋ค.
โ๏ธ API์์์๊ฐ ๊ณ์ฐํ๊ธฐ | โ๏ธ Discord.js๋ฅผ ํตํ Error-bot ๋ง๋ค๊ธฐ
Node.js
๋ ๋น ๋ฅด๊ณ ๊ฐ๋จํ๊ฒ API๋ฅผ ๋ง๋ค ์ ์๋ค๋ ๊ฒ์ ๊ฐ์ ์ด ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ํ์ง๋ง ์๋ฒ๋ ์์ ์ฑ์ด ์ต์ฐ์ ์ด๋ฏ๋ก, TypeScript
๋ฅผ ํตํด ๋์ ํ์
์ธ์ด์ธ Javascript
์์๋ ๊ฒ์ฌํ์ง ๋ชปํ๋ ๋ณ์, ํจ์, ์ธํฐํ์ด์ค ๋ฑ์ ํ์
์ค๋ฅ๋ฅผ ์ฌ์ ์ ์ต๋ํ ์ฐจ๋จํ์๊ณ . ์ด๋ก ์ธํด ๋ฐํ์ ์์ ์ ํ์
๊ด๋ จ ๋ฒ๊ทธ๋ฅผ ์ฌ์ ์ ๋ฐฉ์ง ํ์์ต๋๋ค.
์ฝ๋ ์คํ์ผ์ ์ผ๊ด์ฑ ์๊ฒ ์ ์งํ๊ณ ํํ ๋ฐ์ํ๋ ์ค์๋ ์ ์ฌ์ ์ธ ์ค๋ฅ๋ฅผ ์ฌ์ ์ ๊ฐ์งํ๊ธฐ ์ํด prettier
๋ฅผ ์ฌ์ฉํ์์ต๋๋ค.
"lint-staged": {
"./src/**/*.{ts,tsx,js,jsx}": [
"eslint --fix"
]
}
์ค๋ฅ๊ฐ ์๋ ์ฝ๋๋ lint์ ๋ง์ง ์๋ ์ฝ๋๊ฐ ์ฌ๋ผ์ develop์ merge๋๋ ๊ฒ์ ๋ง๊ธฐ์ํด Husky
๋ฅผ ์ฌ์ฉํ์ฌ commit๊ณผ push์ ์ ์ฑ
์ ์ ์ฉํ์์ต๋๋ค.
> npm run lint-staged
lint-staged
๋ช
๋ น์ด๋ฅผ ํตํด ๋ณ๊ฒฝ๋ ํ์ผ๋ค๋ง ๋์์ผ๋ก lint๋ฅผ ์คํํ์ฌ commit ์ ์ ์๋ฌ๋ฅผ ํ์ธํ์์ต๋๋ค.
> tsc --noEmit
tsc --noEmit
๋ช
๋ น์ด๋ฅผ ํตํด TypeScript ํ์ผ์ ์ปดํ์ผํ์ฌ JavaScript ํ์ผ์ ์์ฑํ์ง ์๊ณ , ํ์
๊ฒ์ฌ๋ง ์ํํ ๋ค์, ํต๊ณผํ๋ฉด push๊ฐ ๋๋๋ก ํ์์ต๋๋ค.
โ๏ธ Husky๋ฅผ ์ด์ฉํ git hook ์ ์ฉํ๊ธฐ
Jest ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด์ฉํ์ฌ API๋ฅผ ์์ฑํ ๋ ํด๋น API์ ๋ํด์ ํ ์คํธ๋ฅผ ์์ฑํ์ฌ ๋ฒ๊ทธ๋ฅผ ๋น ๋ฅด๊ฒ ๊ฐ์งํ๊ณ ์ฝ๋์ ์์ ์ฑ์ ๋์์ต๋๋ค. ๋ํ husky๋ฅผ ํตํด push์ ์ ํ ์คํธ๋ฅผ ์งํํ์ฌ ํ ์คํธ๋ฅผ ํต๊ณผํ์ง ๋ชปํ API๊ฐ ์์์์ ์ฝ๋๊ฐ ๋ณํฉ๋์ง ์๊ฒ ์กฐ์นํ์์ต๋๋ค.
โ๏ธ Jest๋ฅผ ํตํ ํ ์คํธ ์ฃผ๋ ๊ฐ๋ฐ
Docker ์ปจํ ์ด๋๊ฐ ์ ํ๋ฆฌ์ผ์ด์ ๊ณผ ๊ทธ ์คํ์ ํ์ํ ๋ชจ๋ ์ข ์์ฑ๋ค์ ํฌํจํ๊ณ ์๊ธฐ ๋๋ฌธ์, ์ฐ๋ฆฌ์ ์๋น์ค๋ฅผ Docker๋ก ์ปจํ ์ด๋ํ ํ์ฌ ๊ฐ๋ฐ ํ๊ฒฝ๊ณผ ํ๋ก๋์ ํ๊ฒฝ ์ฌ์ด์ ์ผ๊ด์ฑ์ ์ ์งํ์์ต๋๋ค. ๋ํ ๋ค์ํ ํ๋ซํผ๊ณผ ํ๊ฒฝ์์ ์ผ๊ด์ฑ ์๊ฒ ๋ฐฐํฌํ ์ ์๊ฒ ํ์์ต๋๋ค.
Docker๋ ํธ์คํธ OS์ ๋ฆฌ์์ค๋ฅผ ๊ณต์ ํ์ฌ ์คํ๋์ด ๊ฐ์ํ ๋ฐฉ์์ ๋นํด ๋ ์ ์ ๋ฆฌ์์ค๋ฅผ ์๋นํ๊ธฐ ๋๋ฌธ์ ์ฐ๋ฆฌ์ ์๋น์ค๋ฅผ Docker๋ก ์ปจํ ์ด๋ํ ํ์ฌ ๋ ํจ์จ์ ์ธ ์์ ๊ด๋ฆฌ์ ๋์ ์๋ฒ ํ์ฉ๋ฅ ์ ์ป์ ์ ์๊ฒ ํ์์ต๋๋ค.
โ๏ธ Docker๋ ๋ฌด์์ด๊ณ ์ ์ฌ์ฉํ ๊น?
.dockerignore
์ Docker ์ด๋ฏธ์ง๋ฅผ ๋น๋ํ ๋ ํฌํจํ์ง ์์ ํ์ผ์ด๋ ๋๋ ํ ๋ฆฌ๋ฅผ ์ง์ ํ์ฌ, ์ด๋ฏธ์ง ํฌ๊ธฐ๋ฅผ ๊ฒฝ๋ํ ํ์์ต๋๋ค.
โ๏ธ Docker ์ด๋ฏธ์ง ๊ฒฝ๋ํ ํ๊ธฐ
docker-compose.yml
ํ์ผ์ ์ปจํ
์ด๋๋ฅผ ์คํํ๋๋ฐ ํ์ํ ๋คํธ์ํฌ, ๋ณผ๋ฅจ, ํ๊ฒฝ ๋ณ์ ๋ฑ์ ์ ์ํ์ฌ. ๊ฐ๋
์ฑ์ด ์ข๊ฒ ํ์๊ณ , ์ ํ๋ฆฌ์ผ์ด์
๊ตฌ์ฑ์ ์ดํดํ๊ณ ๊ณต์ ํ๊ธฐ ์ฝ๊ฒ ํ์์ต๋๋ค.
docker/build-push-action@v4
๋ฅผ ์ด์ฉํ์ฌ DockerFile์ ์์ฑ๋ ๋๋ก ์ฐ๋ฆฌ์ ์๋น์ค๋ฅผ ์ด๋ฏธ์ง๋ก ๋ง๋ค์ด Github packages
์ ์ ์ฅ๋๋๋ก ํ์์ต๋๋ค.
Github packages
์ ์ ์ฅ๋ ์ด๋ฏธ์ง๋ฅผ appleboy/ssh-action@master
๋ฅผ ์ด์ฉํ์ฌ ์ฐ๋ฆฌ์ ํด๋ผ์ฐ๋ ์๋ฒ์ ์ ๊ทผํ์ฌ ์ด๋ฏธ์ง๋ฅผ ์ปจํ
์ด๋ํ ํ์ฌ ์๋น์ค๋ฅผ ์คํํ ์ ์๊ฒ ํ์์ต๋๋ค.
Action secrets
์ ์ฐ๋ฆฌ์ ํ๊ฒฝ๋ณ์๋ค์ ๋ฃ์ด์ ์ด๋ฏธ์ง๊ฐ ๋น๋๋ ๋ ํ๊ฒฝ๋ณ์๋ก ์ฃผ์
ํ์ฌ .giitignore์ ํฌํจ๋์ด GIthub์ ๋ก๋ ๋์ง ์๋ ํ๊ฒฝ๋ณ์๋ค์ ๊ด๋ฆฌํ์์ต๋๋ค.
โ๏ธ Github-action์ ํตํ CI/CD
Winston.js๋ก ๊ธฐ๋กํ ์ฐ๋ฆฌ ์๋ฒ์ ๋ก๊ทธ๋ค์ ๊ธฐ๋กํ ํด๋๋ฅผ volume์ ์ฐ๊ฒฐํ๊ณ Filebeat
๋ํ ์ปจํ
์ด๋๋ก ์คํํ ๋ค์ volume์ผ๋ก ์ฐ๊ฒฐํ์ฌ ๋ก๊ทธ๊ฐ ์์ผ๋๋ง๋ค Filebeat๊ฐ Elasticsearch๋ก ์ฐ๋ฆฌ๋ค์ ๋ก๊ทธ๋ฅผ ๋ณด๋ด๊ฒ ๋ง๋ค์์ต๋๋ค.
โ๏ธ Filebeat๋ฅผ ์ด์ฉํด ์๋ฒ ๋ก๊ทธ ์๋นํ๊ธฐ
nginx
๋ฅผ ๋์
ํ์ฌ ์ ์ ์ธ ์ปจํ
์ธ ์ ๋ํด์ nginx
๊ฐ ์ฒ๋ฆฌํด ์ฃผ๊ธฐ ๋๋ฌธ์ Node.js๋ก ๊ตฌ๋๋๊ณ ์๋ WAS์ ๋ํด ๋ถ๋ด์ ์ค์์ต๋๋ค.
nginx
๋ฅผ ์ด์ฉํด http๋ก 80๋ฒ port์ ๋ค์ด์จ ์์ฒญ๋ค์ ๋ํด์ ๋๋ฆฌ๋ก ๋ฐ์ ๋ค์, 443๋ฒ port๋ก redirect์์ผ์ ๋ณด๋ด์ฃผ๊ณ . reverse-proxy
๋ฅผ ์ด์ฉํด 4000๋ฒ์์ ์๋ํ๊ณ ์๋ node.js์๋ฒ๋ก ์์ฒญ์ด ๊ฐ๊ฒ ํ์์ต๋๋ค. ์ด๋ ๊ฒย ๋ฆฌ๋ฒ์ค ํ๋ก์๋(reverse-proxy)
๋ฅผ ํตํด ์๋ฒ๋ฅผ ๊ฐ์ถ๊ณ , SSL/TLS ์ํธํ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์์ ํ๊ฒ ์ ์กํ ์ ์๊ฒ ํ์์ต๋๋ค.
โ๏ธ Http์ Https ๊ทธ๋ฆฌ๊ณ SSL์ ๊ฐ๊ฐ ๋ฌด์์ผ๊น? | โ๏ธ Nginx๋ ๋ฌด์์ด๊ณ ์ ์ฌ์ฉํ ๊น? | โ๏ธ Nginx ์ค์น ๋ฐ Https ์ ์ฉํ๊ธฐ
6379 port ์์ ์๋ํ๊ณ ์๋ redis ์ปจํ ์ด๋๊ฐ ์ธ๋ถ์ ์ ๊ทผ์ ๋ฐ์, ์์๋ก ๋ฐ์ดํฐ๊ฐ ๋ชจ๋ ๋ ๋ผ๊ฐ ๋ฒ๋ฆฌ๋ ํ์์ด ๋ฐ์ํ์์ต๋๋ค.
๋ฐ๋ผ์ 6379๋ฒ์ ๋ฐฉํ๋ฒฝ์ ์ฐจ๋จํ์ฌ ์ธ๋ถ ์ ๊ทผ์ ๋ง๊ณ ๋์ปค ๋คํฌ์ํฌ๋ฅผ ์ด์ฉํด ์๋ฒ์ ๋ ๋์ค๊ฐ ์ํตํ ์ ์๋๋ก ๋ง๋ค์ด ์ฃผ์์ต๋๋ค.
โ๏ธ ๋ฐฉํ๋ฒฝ ์ค์ ๋๋ฌธ์ redis์ ๋ฐ์ดํฐ๊ฐ ์ญ์ ๋๋ ๋ฌธ์ ํด๊ฒฐ
๋ฐฉํ๋ฒฝ์ ์ฐจ๋จํ์ฌ๋, ๊ณ์ํด์ ๊ณต๊ฒฉ์ด ๋ค์ด์ cloud๋จ๊ณผ os๋จ์ ๋ฐฉํ๋ฒฝ ๊ท์น์ ๊ฐํํ์ฌ ์๋ฒ์ ์ ์ฉํ์์ต๋๋ค.
โ๏ธ ์๋ฒ ๋ฐฉํ๋ฒฝ ์ ์ฑ ๊ฐํํ๊ธฐ
dotenv.config()๋ฅผ ํ๋ก์ ํธ ์ต์๋จ์ ์ ์ธํ์์ง๋ง, ์ฑ๊ธํด์ผ๋ก ์์ฑํ Redis๋ฅผ ์ฐ๊ฒฐํ๋ ํจ์๊ฐ
dotenv.config() ๋ณด๋ค ๋จผ์ ์คํ๋์ด, Redis์ ์ฐ๊ฒฐ์ด ๋์ง ์๋ ํ์์ด ๋ฐ์ํ์์ต๋๋ค.
JavaScript์์ static ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ธ๋ ๋ณ์๋ ํด๋์ค๊ฐ ๋ก๋๋ ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ด๊ธฐํ ๋๋ค๋ ์ฌ
์ค์ ์์๊ณ , ํด๋น ๋ณ์๋ฅผ ์ธ์คํด์ค ๋ณ์๋ก ์์ ํ์ฌ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์์ต๋๋ค.
โ๏ธ staic์ผ๋ก ์ ์ธํ ๋ณ์๋ ์ธ์ ๋ก๋๋๋๊ฐ?
Discord.js๋ก 2000ms ์ด์ ์์๋๋ API์ ๋ํด ์๋ฆผ์ ๋ณด๋ด๋๋ก ํ์๋๋ฐ, ์๋ฆผ์ด ์จ ๋ฌธ์ ์ API์ ๋ํด
์์ฑ/์์ ๋ณด๋จ ์กฐํ๊ฐ ๋ง์ด ์ผ์ด๋๋ ์๋น์ค์์ ๊ฐ์ํ์ฌ, ์์ฑ๋จ์์ ์ฒ๋ฆฌํ ์ ์๋ ์์ ์ Database
table์ ์ column์ ์ถ๊ฐํ๋ ์์ ์ ํตํด ์์ฑ ๋ฐ ์์ ์์ ์ฒ๋ฆฌํ์๊ณ , Promise.all์ ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ์ด์ฉ
ํ์ฌ API ์ํ์๊ฐ์ ๋จ์ถํ์์ต๋๋ค.
โ๏ธ Promise.all๊ณผ DB column์ถ๊ฐ๋ก ์ธํ API ์์์๊ฐ ๋จ์ถ