Skip to content

jack0928/peekle-api-server

ย 
ย 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Peekle Backend ๐Ÿš€

Table of Contents ๐Ÿ“š

  1. How To ?
  2. Before We Start
  3. Conventions & Template
  4. Git Convention : Strategy
  5. Git Convention : Commit
  6. Code Convention
  7. Project Architecture

How To ? ๐Ÿ› ๏ธ

  • ์„ค์น˜ ๋ฐ ์‹คํ–‰ ๋ฐฉ๋ฒ•์„ ์ž‘์„ฑํ•  ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค. (์˜ˆ์ •)

commit ๋ฐ push ์ „์— npm run format์„ ํ†ตํ•ด prettier ํฌ๋งทํŒ…์„ ์ ์šฉํ•ด์ฃผ์„ธ์š”.

Template Repository URL -> Click
made and owned by @kyeoungwoon | Naver Blog

Git Convention : GitHub Flow ๐ŸŒ

  • ๋ธŒ๋žœ์น˜ ์ข…๋ฅ˜ : main, develop, feature
  • MVP ๊ฐœ๋ฐœ ์™„๋ฃŒ ์ „๊นŒ์ง€๋Š” develop branch๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , main๊ณผ feature ๋ธŒ๋žœ์น˜๋งŒ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.

1. main

  • Production ํ™˜๊ฒฝ์— ์–ธ์ œ ๋ฐฐํฌํ•ด๋„ ๋ฌธ์ œ ์—†๋Š” stable branch ์ž…๋‹ˆ๋‹ค.
  • ์žฅ์•  ํ˜น์€ ๋ฒ„๊ทธ ๋ฐœ์ƒ ์‹œ main branch๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋น ๋ฅด๊ฒŒ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.
  • Initial commit์„ ์ œ์™ธํ•˜๊ณ , main branch์— commit์ด ์ง์ ‘์ ์œผ๋กœ ๋ฐœ์ƒํ•˜๋ฉด ์•ˆ๋ฉ๋‹ˆ๋‹ค.

2. develop

  • ์ƒˆ๋กœ์šด feature๋“ค์„ ๊ฐœ๋ฐœํ•  ๊ฒฝ์šฐ main์„ ๊ธฐ์ค€์œผ๋กœ develop branch๋ฅผ ์ƒ์„ฑ ํ•ฉ๋‹ˆ๋‹ค.
  • feature branch๋“ค์„ merge ํ•˜๋Š” ๊ณณ์ž…๋‹ˆ๋‹ค.
  • feature๋“ค์„ ๋ชจ๋‘ mergeํ•œ ํ›„ ๋ฐœ์ƒ๋˜๋Š” bug fix๋ฅผ ๋ชจ๋‘ ๋งˆ์นœ ํ›„, main branch๋กœ PR์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ๋‹ค์‹œ ํ•œ๋ฒˆ ๊ฐ•์กฐํ•˜์ง€๋งŒ, main branch๋Š” ๋ชจ๋“  ์ž‘์—…์˜ ์‹œ์ž‘์ ์ด๋ฉฐ, ์ ˆ๋Œ€์ ์œผ๋กœ stable ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ถˆ์™„์ „ํ•œ ์‚ฌํ•ญ๋“ค์€ develop branch ๋‚ด์—์„œ ํ•ด๊ฒฐ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

3. feature

  • ์ด ํ”„๋กœ์ ํŠธ๋Š” issue๋ฅผ ํ†ตํ•ด branch๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ธŒ๋žœ์น˜ ๋ช…์€ ๋ฐ˜๋“œ์‹œ feature/{issue๋ฒˆํ˜ธ}-{feature๋ช…} ๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์ด์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. eg.) feature/1-sample
  • develop branch๋ฅผ ๊ธฐ์ค€์œผ๋กœ, ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ๊ฐœ๋ฐœํ•˜๋Š” branch ์ž…๋‹ˆ๋‹ค.
  • ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ bug fix๋Š” feature branch ๋‚ด์—์„œ ๋งˆ์นœ ํ›„ develop branch๋กœ PR์„ ์ƒ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Git Convention : Commit ๐Ÿ“

์ œ๋ชฉ, ๋ณธ๋ฌธ, ๊ผฌ๋ฆฌ๋ง ์„ธ ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋‰ฉ๋‹ˆ๋‹ค.
๊ฐ ๋ถ€๋ถ„์€ ๋นˆ ์ค„๋กœ ๊ตฌ๋ถ„๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ œ๋ชฉ

Tag: Title ์˜ ํ˜•์‹์„ ์‚ฌ์šฉํ•ด ์ฃผ์„ธ์š”.

  • Tag์˜ ์ฒซ ๋ฌธ์ž๋Š” ๋Œ€๋ฌธ์ž๋กœ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ์ฝœ๋ก ์€ Tag์— ๋ถ™์—ฌ์„œ ์ž‘์„ฑํ•˜๊ณ , ์ฝœ๋ก  ์ดํ›„ 1์นธ ๋’ค์— title์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
    • (X)
      • feat:title feat: title feat :title feat : title
      • Feat :title Feat : title
    • (O)
      • Feat: title

Tag์˜ ์ข…๋ฅ˜์™€ ๊ทธ ๊ตฌ๋ถ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • Feat : ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋˜์—ˆ์„ ๋•Œ
  • Fix : ๋ฒ„๊ทธ๋ฅผ ์ˆ˜์ •ํ•˜์˜€์„ ๋•Œ
  • Docs : README.md๋‚˜ ์ฃผ์„ ๋“ฑ ๋ฌธ์„œ๋ฅผ ์ˆ˜์ •ํ•˜์˜€์„ ๋•Œ
  • Style : ์ฝ”๋“œ ๊ตฌ์กฐ์— ๋ณ€๊ฒฝ ์—†์ด ๋ณ€์ˆ˜๋ช… ๋“ฑ์„ ์ˆ˜์ •ํ•˜์˜€์„ ๋•Œ
  • Refactor : ์ฝ”๋“œ ๋™์ž‘ ๋ฐฉ์‹์„ ์ˆ˜์ •ํ•˜์˜€์„ ๋•Œ, ๋˜๋Š” Style์„ ๋Œ€๊ทœ๋ชจ๋กœ ๋ณ€๊ฒฝํ•˜์˜€์„ ๋•Œ์—๋„ ํ™œ์šฉ.
  • Test : ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์˜€์„ ๋•Œ
  • Chore : package.json์„ ์ˆ˜์ •ํ•˜์˜€๊ฑฐ๋‚˜ dockerfile ๋“ฑ ๋ถ„๋ฅ˜ํ•˜๊ธฐ ์• ๋งคํ•œ ์ƒํ™ฉ์—์„œ ์‚ฌ์šฉ
  • Merge : branch๋ฅผ mergeํ•˜์˜€์„ ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋ณธ๋ฌธ

  • ๋ณธ๋ฌธ์€ ํ•œ ์ค„ ๋‹น 72์ž ๋‚ด๋กœ ์ž‘์„ฑํ•ด ์ฃผ์„ธ์š”. (๋‹ค์–‘ํ•œ ํ™˜๊ฒฝ์—์„œ์˜ ๊ฐ€๋…์„ฑ์„ ์œ„ํ•˜์—ฌ)
  • ๋ณธ๋ฌธ ๋‚ด์šฉ์€ ์–‘์— ๊ตฌ์• ๋ฐ›์ง€ ์•Š๊ณ  ์ตœ๋Œ€ํ•œ ์ƒ์„ธํžˆ ์ž‘์„ฑํ•ด ์ฃผ์„ธ์š”.
  • ๋ณธ๋ฌธ ๋‚ด์šฉ์€ ์–ด๋–ป๊ฒŒ ๋ณ€๊ฒฝํ–ˆ๋Š”์ง€ ๋ณด๋‹จ, ๋ฌด์—‡์„ ๋ณ€๊ฒฝํ–ˆ๋Š”์ง€ ๋˜๋Š” ์™œ ๋ณ€๊ฒฝํ–ˆ๋Š”์ง€๋ฅผ ์„ค๋ช…ํ•ด ์ฃผ์„ธ์š”.

๊ผฌ๋ฆฌ๋ง

Type: #issue_number ์˜ ํ˜•์‹์„ ์‚ฌ์šฉํ•ด ์ฃผ์„ธ์š”.

  • Footer๋Š” ํ•„์ˆ˜์ ์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ๋‹ค๋งŒ, issue์— ์—ฐ๊ด€๋˜์–ด ์ƒ์„ฑ๋œ commit์ด๋ผ๋ฉด ๋„ฃ์–ด์ฃผ์‹œ๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค.
  • ์ œ๋ชฉ์„ ์“ธ ๋•Œ์™€ ํ˜•์‹์€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.
    • eg. Fixes: something

Type์˜ ์ข…๋ฅ˜์™€ ๊ตฌ๋ถ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • Fixes : ์ด์Šˆ ์ˆ˜์ •์ค‘ (์•„์ง ํ•ด๊ฒฐ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ)
  • Resolves : ์ด์Šˆ๋ฅผ ํ•ด๊ฒฐํ–ˆ์„ ๋•Œ ์‚ฌ์šฉ
  • Ref : ์ฐธ๊ณ ํ•  ์ด์Šˆ๊ฐ€ ์žˆ์„ ๋•Œ ์‚ฌ์šฉ
  • Related to : ํ•ด๋‹น ์ปค๋ฐ‹์— ๊ด€๋ จ๋œ ์ด์Šˆ๋ฒˆํ˜ธ (์•„์ง ํ•ด๊ฒฐ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ)

Code Convention ๐Ÿ’ป

ํ•จ์ˆ˜๋ช…

  • Camel Case๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
    • eg. getUserByUserId, getEventByDateAndUserId
  • ๊ธธ์ด๊ฐ€ ๊ธธ์–ด์ง€๋”๋ผ๋„ ๊ธฐ๋Šฅ์„ ๋ช…ํ™•ํ•˜๊ฒŒ ๋ช…์‹œํ•ด ์ฃผ์„ธ์š”.
  • ํ•จ์ˆ˜๋ช…์€ ๊ฒน์ณ๋„ ๋˜์ง€๋งŒ, Import/Export์— ์œ ์˜ํ•ด ์ฃผ์„ธ์š”.
    • ํ•˜๋‹จ์— import/export ๊ด€๋ จ ์ปจ๋ฒค์…˜ ์„ค๋ช…์—์„œ ๋” ์ž์„ธํžˆ ์•Œ ์ˆ˜ ์žˆ์ง€๋งŒ, ์•„๋ž˜์˜ ๊ฐ„๋‹จํ•œ ์˜ˆ์‹œ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”.
    • user.service.js ์— createNewUser ๊ณผ user.repository.js์— createNewUser์ด ๋™์‹œ์— ์กด์žฌํ•˜์—ฌ๋„ ๋ฉ๋‹ˆ๋‹ค.
    • service์—์„œ ์‚ฌ์šฉ ์‹œ์—๋Š” userRepository.createNewUser
    • controller์—์„œ ์‚ฌ์šฉํ•  ๋–„๋Š” userController.createNewUser์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • routes ํด๋”์—์„œ express.Router()๋กœ ์ •์˜ํ•˜๋Š” ๋ณ€์ˆ˜๋ช…์€ router๋กœ ํ†ต์ผํ•ฉ๋‹ˆ๋‹ค.
    • eg. const router = express.Router();

๋ณ€์ˆ˜๋ช…

  • ์•„๋ž˜ ์˜ˆ์™ธ๋ฅผ ์ œ์™ธํ•œ ๋ชจ๋“  ๊ฒฝ์šฐ์— Camel Case๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ์ƒ์ˆ˜๊ฐ’์— ํ•ด๋‹นํ•˜๋Š” ๋ณ€์ˆ˜๋ช…์€ ์ „๋ถ€ ๋Œ€๋ฌธ์ž ๋ฐ snake case๋กœ ์ž‘์„ฑ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    • ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๋“ฑ์ด ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค. eg. AWS_SECRET_KEY, API_KEY ๋“ฑ
  • JSON ๊ฐ์ฒด ์•ˆ์—์„œ๋„ Camel Case๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • DB Query๋ฌธ์„ ์ž‘์„ฑํ•  ๋•Œ๋„ ORM์„ ํ†ตํ•ด Camel Case๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์‚ฌ์šฉํ•˜์…”์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํŒŒ์ผ๋ช…

  • ์ „๋ถ€ ์†Œ๋ฌธ์ž๋ฅผ ์‚ฌ์šฉํ•˜์…”์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ์ƒ์œ„ ํด๋”๋ช…์„ ํฌํ•จํ•˜์—ฌ ๊ธฐ๋Šฅ์„ ๋ช…์‹œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ์—ฌ๋Ÿฌ ๋‹จ์–ด๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ . ์œผ๋กœ ๋‹จ์–ด๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค
  • eg. user.repository.js, chat.service.js

ํด๋”๋ช…

  • ํด๋”๋ช…์€ ๋˜๋„๋ก ํ•œ ๋‹จ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋˜, ๊ธธ์–ด์งˆ ๊ฒฝ์šฐ -๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. (kebab case)
  • eg. my-page, user-info

Error Handling

  • class CustomError extends Error์™€ ๊ฐ™์ด, JavaScript ๊ธฐ๋ณธ Error ๊ฐ์ฒด๋ฅผ extend ํ•˜์—ฌ Custom Error๋ฅผ ์ž‘์„ฑํ•˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • Error๋Š” ์„ธ๋ถ„ํ™”ํ•˜์—ฌ ๊ฐ๊ฐ ์—๋Ÿฌ๋ฅผ ํ• ๋‹นํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ, ๋Œ€๋ถ„๋ฅ˜๋กœ ๊ด€๋ฆฌํ•˜์—ฌ reason์œผ๋กœ ์„ธ๋ถ€์‚ฌํ•ญ์„ ์•Œ ์ˆ˜ ์žˆ๋„๋ก ํ•˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • Error ๋ช…์€ Pascal Case๋กœ ์ž‘์„ฑํ•˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    • UserNotExistError UserAuthorizationError IdNotProvidedError ๋“ฑ๊ณผ ๊ฐ™์ด ์„ธ๋ถ„ํ™” ๋œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ,
    • NotExistError InvalidInputError ์ฒ˜๋Ÿผ ์ตœ๋Œ€ํ•œ ํฌ๊ด„์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    • ์„ธ๋ถ„ํ™”ํ•  ํ•„์š”๊ฐ€ ์ƒ๊ธด๋‹ค๋ฉด, UserIdNotExist UserNameNotExist ์ˆ˜์ค€์œผ๋กœ ์„ธ๋ถ„ํ™” ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ, InvalidUserDataInput ๊ณผ ๊ฐ™์ด ์นดํ…Œ๊ณ ๋ฆฌ๊นŒ์ง€๋งŒ ํฌํ•จํ•˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ์ˆ˜์ •์€ ์ž์œ ์ด๋‚˜, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์‚ฌํ•ญ์„ ํฌํ•จํ•˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    • error code
      • string ์ด์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
      • U001๊ณผ ๊ฐ™์ด ๋”ฐ๋กœ ์ •์˜ํ•ด๋‘์…”๋„ ๋˜๊ณ , ALREADY_EXIST์™€ ๊ฐ™์ด ํ•œ๋‘ ๋‹จ์–ด ์ •๋„๋กœ ๊ฐ„๋žตํ•˜๊ฒŒ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.
      • U001๊ณผ ๊ฐ™์ด ์ฝ”๋“œ๊ฐ’์œผ๋กœ ๊ด€๋ฆฌํ•˜์‹ค ์˜ˆ์ •์ด๋ฉด, ๋ฌธ์„œํ™” ํ•˜์—ฌ ํŒ€์›๋“ค ์‚ฌ์ด์— ๊ณต์œ ํ•ด ์ค‘๋ณต๋œ ์—๋Ÿฌ๊ฐ€ ์ž‘์„ฑ๋˜์ง€ ์•Š๋„๋ก ์œ ์˜ํ•ด์ฃผ์„ธ์š”.
    • status code
      • http status code ๊ฐ’ ์ž…๋‹ˆ๋‹ค.
      • ํ•ด๋‹น ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์ „์†กํ•  status code๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.
    • reason
      • ํ•ด๋‹น ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ์ด์œ ์ž…๋‹ˆ๋‹ค.
      • debug ์‹œ์— reason๋งŒ ๋ณด๊ณ  ์•Œ ์ˆ˜ ์žˆ๋„๋ก ๊ฐ„๊ฒฐํ•˜๋˜, ๋ชจ๋“  ์ •๋ณด๋ฅผ ํฌํ•จํ•˜๋„๋ก ์ž‘์„ฑํ•ด ์ฃผ์„ธ์š”.

class AlreadyExistError extends Error {
  errorCode = "ALREADY_EXIST";
  statusCode = 409;

  constructor(reason, data) {
    super(reason);
    this.reason = reason;
    this.data = data;
  }
}

Database ๐Ÿ—„๏ธ

MySQL์„ ๊ธฐ์ค€์œผ๋กœ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

  • ํ…Œ์ด๋ธ”๋ช…๊ณผ ์ปฌ๋Ÿผ๋ช… ๋“ฑ ๋ชจ๋“  ๋ณ€์ˆ˜๋ช…์€ ๋ฐ˜๋“œ์‹œ snake case๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. (ERD ์ƒ์„ฑ ์‹œ๋ฅผ ๋งํ•˜๋Š” ๊ฒƒ์ด๋ฉฐ, MySQL์€ ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.)
  • PK๊ฐ’์€ {table๋ช…}_id ์™€ ๊ฐ™์€ ํ˜•์‹์ด์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋„ˆ๋ฌด ๊ธธ์–ด์งˆ ๊ฒฝ์šฐ PK์ธ ๊ฐ’์ž„์„ ์•Œ ์ˆ˜ ์žˆ๋„๋ก ์ถ•์•ฝํ•˜์—ฌ ์‚ฌ์šฉ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
    • eg1. user_oauth ํ…Œ์ด๋ธ”์˜ PK ์ปฌ๋Ÿผ ๋ช…์€ user_oauth_id
    • eg2. user_profile_images ํ…Œ์ด๋ธ”์˜ PK -> image_id
    • bigint ์ž๋ฃŒํ˜•์„ ์‚ฌ์šฉํ•˜๊ณ , auto increment์„ ์‚ฌ์šฉํ•˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    • ๋ฐ˜์ •๊ทœํ™” (๋น„์ •๊ทœํ™”, denormailzation)๋กœ ์ธํ•ด ํ…Œ์ด๋ธ”์ด ๋ถ„ํ• ๋œ ๊ฒฝ์šฐ์—๋„, id๊ฐ’์„ ๋”ฐ๋กœ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค.
  • ๋ชจ๋“  ํ…Œ์ด๋ธ”์—๋Š” created_at๊ณผ updated_at์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    • DataType์€ TIMESTAMP(6) ์ž…๋‹ˆ๋‹ค.
    • created_at๊ณผ updated_at์€ default expression์— current_timestamp(6)์„ ์ ์šฉํ•ด๋‘์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    • updated_at์€ on_update์— current_timestamp(6)์ด ์ ์šฉ๋˜์–ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ์ •๊ทœํ™” ๊ทœ์น™์„ ๋˜๋„๋ก์ด๋ฉด ๋”ฐ๋ฅด๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค.
  • ๊ฐ™์€ ๋‚ด์šฉ์˜ Query๋ฅผ ์—ฌ๋Ÿฌ๋ฒˆ ๋‚ ๋ฆฌ๋Š” ๊ฒƒ ๋ณด๋‹ค๋Š”, JOIN์ด๋‚˜ BETWEEN ๋“ฑ์œผ๋กœ ํ•œ๋ฒˆ์— ๊ฐ€์ ธ์™€์„œ Node.js๋‹จ์—์„œ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ๊ถŒํ•ฉ๋‹ˆ๋‹ค.
  • image๋“ฑ ํŒŒ์ผ์€ url์ด๋‚˜ uuid๋“ฑ์„ ์ €์žฅํ•˜๊ณ , binary data๋ฅผ ์ง์ ‘ ์ €์žฅํ•˜๋Š” ์ผ์€ ํ”ผํ•ด์ฃผ์„ธ์š”.

import / export ๐Ÿ“ฆ

ES6์™€ commonJS ๋ชจ๋‘ ๋™์ผํ•˜๊ฒŒ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.

  • default export์˜ ์‚ฌ์šฉ์„ ์ง€์–‘ํ•˜๊ณ ,
  • named export์˜ ์‚ฌ์šฉ์„ ์ง€ํ–ฅํ•ฉ๋‹ˆ๋‹ค.
// ์ง€์–‘ : ํ•จ์ˆ˜๋ฅผ ์ง์ ‘ import ํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ
import { createNewUser } from "./user.service";

const result = createNewUser();
// user.repository์—๋„ createNewUser ์กด์žฌํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๊ธฐ์—, ์ถฉ๋Œํ•  ์šฐ๋ ค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

// ์ง€ํ–ฅ : ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ๊ตฌ์กฐํ™” ํ•ฉ๋‹ˆ๋‹ค.
// eg. Java, C++

import userService from "./sample.service.js";

const result = userService.createNewUser();

์ปจ๋ฒค์…˜์„ ๋ชจ๋‘ ์ง€ํ‚จ, router - controller - service - repository ๊ฐ„์˜ ํ˜ธ์ถœ๊ตฌ์กฐ ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค.

// user.router.js
import userController from "./user.controller";

const userRouter = express.Router();
userRouter.get("/", userController.createNewUser);

// user.controller.js
import userService from "./user.service";

export const createNewUser = async (req, res, next) => {
  const { id, password } = req.body;
  // ์ด๋ ‡๊ฒŒ๋„ ๋˜๊ณ 
  await userService.createNewUser({ id, password }); // RORO
  // ์ด๋ ‡๊ฒŒ ํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค.
  const data = { id, password };
  userService.createNewUser(data);

  return res.status(200).success();
};

// user.service.js
import userRepository from "./user.repository";

export const createNewUser = async (data) => {
  const result = await userRepository.createNewUser(data);

  return { message: "OK", result };
};

// user.repository.js
export const createNewUser = async (data) => {
  const result = await User.create(data);

  return result;
};

Project Architecture ๐Ÿ—๏ธ

routes

  • ์—”๋“œํฌ์ธํŠธ๋ณ„๋กœ controller๋ฅผ ๋ฌถ๋Š” ์—ญํ• ์„ ํ•˜๋Š” router ํŒŒ์ผ๋“ค์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • /routes/index.js ์—์„œ ๋ชจ๋“  router๋“ค์„ ๋ชจ์•„์„œ export ํ•ฉ๋‹ˆ๋‹ค.

controllers

  • ๊ฐ ์—”๋“œํฌ์ธํŠธ์˜ ์‘๋‹ต์„ ํ•ธ๋“ค๋งํ•ฉ๋‹ˆ๋‹ค.
  • try - catch๋ฅผ ํ†ตํ•ด catchํ•œ error๋ฅผ next๋ฅผ ์ด์šฉํ•ด index.js (๊ฐ€์žฅ ์ƒ๋‹จ) ์˜์—ญ์œผ๋กœ ์—๋Ÿฌ ํ•ธ๋“ค๋ง์˜ ์—ญํ• ์„ ๋„˜๊ฒจ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • service์— ์˜์กด์ ์ž…๋‹ˆ๋‹ค.

service

  • controllers์—์„œ ํ™œ์šฉํ•  ๊ธฐ๋Šฅ ๋“ฑ์„ ์œ„ํ•œ ํด๋”์ž…๋‹ˆ๋‹ค.
  • ์˜์กด์„ฑ์„ ๊ฐ€์ง€์ง€ ์•Š์œผ๋ฉฐ, DB์— ์ฟผ๋ฆฌ๋ฅผ ๋‚ ๋ฆฌ๋Š” ์ž‘์—… ๋˜ํ•œ service๋กœ ๋ถ„๋ฅ˜๋ฉ๋‹ˆ๋‹ค.
  • ์ž…๋ ฅ๊ฐ’ validation์ด๋‚˜ error handling ๋“ฑ์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.

models

  • Seqelize์˜ model ์ •์˜๋ฅผ ์œ„ํ•œ ํด๋”์ž…๋‹ˆ๋‹ค.
  • /models/index.js ์—์„œ model๋กœ named export ๋˜๋Š” ๊ฐ์ฒด๋ฅผ import ํ•˜์—ฌ ๊ทธ ์•ˆ์— ์žˆ๋Š” Sequelize Model ๊ฐ์ฒด๋ฅผ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • JavaScript 100.0%