Skip to content

Latest commit

ย 

History

188 Commits

Folders and files

NameName
Last commit message
Last commit date
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

[ Hello Developer ] ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•œ ์ปค๋ฎค๋‹ˆํ‹ฐ ์„œ๋น„์Šค

Nest

์›น๊ฐœ๋ฐœ์— ์žˆ์–ด ๊ฐœ๋ฐœ ์‚ฌ์ดํด์˜ ์ „๋ฐ˜์ ์ธ ํ๋ฆ„์„ ๊ฒฝํ—˜ํ•˜๊ธฐ ์œ„ํ•ด ์ง„ํ–‰ํ•œ ๊ฐœ์ธ ํ”„๋กœ์ ํŠธ ์ž…๋‹ˆ๋‹ค.

๊ธฐํš, ๋””์ž์ธ๋ถ€ํ„ฐ ์šด์˜๊ณผ ๋ฐฐํฌ๊นŒ์ง€ ์žˆ์–ด ์ „์ฒด์ ์ธ ๊ฐœ๋ฐœ๊ธฐ๊ฐ„์€ 2022.02 ~ 2022.04 ์ž…๋‹ˆ๋‹ค.

๋ชจ๋ฐ”์ผ์—์„œ๋„ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ๋ชจ๋ฐ”์ผ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ์„ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.

์‹ค์ œ ์„œ๋น„์Šค๋Š” ํ—ฌ๋กœ๋””๋ฒจ๋กœํผ ์—์„œ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.


๐ŸŽจ Enviroment

์—๋””ํ„ฐ

  • Visual Studio Code
  • DBeaver
  • Mysql Workbench

๋””์ž์ธ

  • Figma

ETC

  • Notion
  • Slack

๐Ÿ”จ Tech Skills

๐Ÿ–ฅ ๋ฐฑ์—”๋“œ

์–ธ์–ด / ํ”„๋ ˆ์ž„์›Œํฌ

  • Typescript
  • Nestjs

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค

  • Mysql + TypeORM

์ธํ”„๋ผ

  • AWS EC2
  • AWS S3
  • AWS ACM
  • AWS Route53
  • AWS ELB(ALB)
  • AWS RDS
  • AWS ECR
  • Docker

์ธ์ฆ

  • Passport.js
  • JWT

๐Ÿ’ป ํ”„๋ก ํŠธ์—”๋“œ

์–ธ์–ด / ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

  • Typescript
  • React

์ƒํƒœ๊ด€๋ฆฌ

  • Recoil

๋””์ž์ธ

  • Styled-components

์ธํ”„๋ผ

  • AWS S3
  • AWS CloudFront
  • AWS Route53

๐Ÿ”‘ ETC

  • CI/CD : Github Actions
  • Markdown Editor/Viewer : Toast UI Editor

โœDatabase E-R Diagram



โš™ Module Structure

๋ฃจํŠธ ๋ชจ๋“ˆ์ธ Application๋ชจ๋“ˆ์„ ๊ธฐ์ค€์œผ๋กœ ์ด 3๊ฐœ์˜ ๋ฉ”์ธ๋ชจ๋“ˆ์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

  • Auth : ์ธ์ฆ(๋กœ๊ทธ์ธ, ํšŒ์›๊ฐ€์ž…, ํ† ํฐ ๋“ฑ) ๊ด€๋ จ ๋ชจ๋“ˆ
  • Boards : ๊ฒŒ์‹œ๊ธ€(์ž‘์„ฑ, ์‚ญ์ œ ๋“ฑ) ๊ด€๋ จ ๋ชจ๋“ˆ
  • User: ์‚ฌ์šฉ์ž(ํ”„๋กœํ•„, ํ™œ๋™๋‚ด์—ญ ๋“ฑ) ๊ด€๋ จ ๋ชจ๋“ˆ

ํ•˜์œ„ ๋ชจ๋“ˆ์˜ ๊ฒฝ์šฐ Global์ด ์•„๋‹Œ ์ƒ์œ„๋ชจ๋“ˆ์—์„œ ํ•„์š”์— ์˜ํ•˜์—ฌ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

graph TD;
    APP-->Auth;
    APP-->Boards;
    APP-->Users;
		Auth-->Email
		Auth-->Util
		Boards-->Util
		Boards-->AWS
    Boards-->Comments;
		Users-->AWS
Loading


๐ŸŒ System Architecture

๋ฐฐํฌ ๋ฐฉ์‹

EC2์—์„œ Docker๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ฐฐํฌํ•˜์˜€์Šต๋‹ˆ๋‹ค.

AWS ACM์—์„œ ๋ฐœ๊ธ‰๋ฐ›์€ SSL์ธ์ฆ์„œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ELB(ALB)๋ฅผ ํ†ตํ•ด HTTPS๋ฅผ ์ ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ฐฐํฌ๊ณผ์ •์€ ์•„๋ž˜ ๋ธ”๋กœ๊ทธ์— ์ •๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.


CI/CD

Github Actions๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Docker Image๋ฅผ ๋นŒ๋“œํ•˜๊ณ  ECR์— ์—…๋กœ๋“œ ํ•ฉ๋‹ˆ๋‹ค.

EC2์—์„œ๋Š” ECR์— ์—…๋กœ๋“œ๋œ ์ด๋ฏธ์ง€๋ฅผ ๋ฐ›์•„์˜ค๊ณ  Docker Image๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.

CI/CD ๊ตฌ์ถ•๊ณผ์ •์€ ์•„๋ž˜ ๋ธ”๋กœ๊ทธ์— ์ •๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ฐฐํฌ ๋ฐฉ์‹

S3์˜ ์ •์  ์›น ํ˜ธ์ŠคํŒ…์„ ์‚ฌ์šฉํ•˜์—ฌ CloudFront๋กœ ๋ฐฐํฌํ–ˆ์Šต๋‹ˆ๋‹ค.

AWS ACM์—์„œ SSL์ธ์ฆ์„œ๋ฅผ ๋ฐœ๊ธ‰๋ฐ›์•„ HTTPS๋ฅผ ์ ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ฐฐํฌ๊ณผ์ •์€ ์•„๋ž˜ ๋ธ”๋กœ๊ทธ์— ์ •๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.

CI/CD

Github Actions๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฆฌ์•กํŠธ ํ”„๋กœ์ ํŠธ ๋นŒ๋“œ์ดํ›„ S3์— ์—…๋กœ๋“œ๋ฉ๋‹ˆ๋‹ค.

S3์˜ ๋ณ€๊ฒฝ์‚ฌํ•ญ์ด ๋ฐ”๋กœ ์ ์šฉ๋  ์ˆ˜ ์žˆ๋„๋ก CloudFront์—์„œ Invalidate Cache๋ฅผ ์ ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

CI/CD ๊ตฌ์ถ•๊ณผ์ •์€ ์•„๋ž˜ ๋ธ”๋กœ๊ทธ์— ์ •๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.



โœ” Test

Unit Test

๊ฐ API์˜ Controller์™€ Service ๋ ˆ์ด์–ด์— ๋Œ€ํ•œ 90๊ฐœ์˜ ์œ ๋‹›ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

์ƒ์œ„ ๋ ˆ์ด์–ด์— ์˜์กดํ•˜๋Š” ๋กœ์ง์˜ ๊ฒฝ์šฐ ํ…Œ์ŠคํŠธ์˜ ๊ฒฉ๋ฆฌ๋ฅผ ์œ„ํ•˜์—ฌ Mocking ์ฒ˜๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.

์œ ๋‹›ํ…Œ์ŠคํŠธ์˜ ๊ฒฝ์šฐ Auth, User ๋“ฑ๊ณผ ๊ฐ™์ด ๋ชจ๋“ˆ๋ณ„๋กœ ํด๋”์— ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.



E2E Test

๋ชจ๋“  API์— ๋Œ€ํ•œ 65๊ฐœ์˜ E2E ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

ํ…Œ์ŠคํŠธ์‹œ๊ฐ„์„ ์ค„๊ธฐ์ด ์œ„ํ•˜์—ฌ ์‹ค์ œ DB๊ฐ€ ์•„๋‹Œ ์ธ-๋ฉ”๋ชจ๋ฆฌ DB์ธ SQLite๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

E2E ํ…Œ์ŠคํŠธ์˜ ๊ฒฝ์šฐ ๋ฃจํŠธํด๋” ํ•˜์œ„ test ํด๋”์— ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.



๐Ÿ“œ API Docs with Swagger

Restful API์˜ ๋ฌธ์„œ๋ฅผ ์ž๋™์œผ๋กœ ๊ตฌ์„ฑํ•ด์ฃผ๋Š” Swagger ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

API ๋ฌธ์„œ URL : Hello Developer API Docs.

์‚ฌ์šฉ์ž ์ ‘๊ทผ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋กœ๊ทธ์ธ๊ณ„์ •์„ ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. admin / 1234




๐Ÿ“˜ Logging with Sentry, Slack

์„œ๋ฒ„์—์„œ ์น˜๋ช…์ ์ธ 500๋Œ€์˜ HTTP ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๊ฒฝ์šฐ์— ๋กœ๊น…ํ•˜๋„๋ก ์ฒ˜๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.

Sentry ๋‚ด๋ถ€์— ์ƒ์„ธ ๋กœ๊ทธ๋ฅผ ์ €์žฅ



์—๋Ÿฌ ๋ฐœ์ƒ์‹œ ๋ฐ”๋กœ ํ™•์ธ์ด ๊ฐ€๋Šฅํ•˜๋„๋ก Slack์œผ๋กœ ๋ฉ”์„ธ์ง€ ํ‘ธ์‰ฌ๊ธฐ๋Šฅ ๊ตฌํ˜„



โ— ํ•ด๊ฒฐํ–ˆ๋˜ ๋ฌธ์ œ๋“ค...

์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ์ตœ์ ํ™”ํ•˜๊ธฐ

์—๋””ํ„ฐ๋ฅผ ํ†ตํ•ด ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ๋ฐ DB์— ์ €์žฅ์‹œ ์•„๋ž˜์™€ ๊ฐ™์€ ์ƒํ™ฉ์ด ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

  • ๋งˆํฌ๋‹ค์šด ์—๋””ํ„ฐ์—์„œ ์ด๋ฏธ์ง€ ์‚ฝ์ž…์‹œ ์ธ์ฝ”๋”ฉ๋˜์–ด ๋ณธ๋ฌธ์˜ ๊ธธ์ด๊ฐ€ ๊ธธ์–ด์ง€๋Š” ์ƒํ™ฉ
  • ์•ฝ 4kb์˜ ์ด๋ฏธ์ง€ ์‚ฝ์ž…์‹œ ์•ฝ 5100์ž์˜ ๋ฌธ์ž์—ด์ด ์‚ฝ์ž…
  • ๋ณธ๋ฌธ์˜ ๊ธธ์ด๊ฐ€ ๋Š˜์–ด๋‚ ์ˆ˜๋ก DB์—์„œ ์ฐจ์ง€ํ•˜๋Š” ๊ณต๊ฐ„์ด ์ปค์ง€๊ฒŒ๋˜๋ฉฐ, ์‚ฝ์ž…/์‚ญ์ œ ๋“ฑ ๋ฐ์ดํ„ฐ์˜ ํฌ๊ธฐ๊ฐ€ ๋Š˜์–ด๋‚ ์ˆ˜๋ก ๋” ๋งŽ์€์–‘์˜ ๋„คํŠธ์›Œํฌ ํŠธ๋ž˜ํ”ฝ์„ ์š”๊ตฌ

์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ์ด๋ฒคํŠธ๋ฅผ ์ปค์Šคํ…€ํ•˜์—ฌ AWS S3์— ์—…๋กœ๋“œ ๋ฐ ์ด๋ฏธ์ง€ URL์„ ๋ฐ˜ํ™˜ํ•˜์—ฌ ์—…๋กœ๋“œ๋ฅผ ์ตœ์ ํ™” ํ–ˆ์Šต๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ๊ณผ์ •์€ Tistory ๋ธ”๋กœ๊ทธ์— ์ •๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฏธ์ง€ ์—…๋กœ๋“œ์‹œ ๊ฒŒ์‹œ๊ธ€ ID ์ƒ์„ฑ๊ด€๋ จ ์ด์Šˆ

๊ธฐ์กด ๊ฒŒ์‹œ๊ธ€์„ ์ž‘์„ฑํ•˜๋Š” DB Column ์ƒ์„ฑ์‹œ UUID ํ˜•์‹์˜ ๋žœ๋คํ•œ ๊ฒŒ์‹œ๊ธ€ ID๊ฐ€ ์ƒ์„ฑ๋˜๋Š” ํ˜•์‹
ํ•˜์ง€๋งŒ ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ์‹œ์— ๊ฒŒ์‹œ๊ธ€์ด DB์— ์ €์žฅ๋˜๋Š” ์‹œ์ ๋ณด๋‹ค ์ด์ „์— ์—…๋กœ๋“œ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒ

์œ„์™€ ๊ฐ™์€ ๋ฌธ์ œ์ ์„ ์•„๋ž˜์™€ ๊ฐ™์ด ๋ฐฉ๋ฒ•์œผ๋กœ ๊ฐœ์„ ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

  • ๊ฒŒ์‹œ๊ธ€ ์ƒ์„ฑ์‹œ ํด๋ผ์ด์–ธํŠธ์—์„œ ์ž„์‹œ ๊ฒŒ์‹œ๊ธ€ ID ์ƒ์„ฑ
  • ์ž„์‹œ ๊ฒŒ์‹œ๊ธ€ ID๋ฅผ ๊ธฐ์ค€์œผ๋กœ S3์— /temp-board-id/image.png ํ˜•์‹์œผ๋กœ ์—…๋กœ๋“œ
  • ๊ฒŒ์‹œ๊ธ€์ด ์ €์žฅ๋˜๋Š” ์‹œ์ ์— ๊ฒŒ์‹œ๊ธ€ DTO์— UUID ๋ฌธ์ž์—ด์„ ID๋กœ ์ถ”๊ฐ€
  • ๊ฒŒ์‹œ๊ธ€์ด ์ €์žฅ๋˜๋Š” ๋™์‹œ์— S3์— ์กด์žฌํ•˜๋Š” temp-board-id๋ฅผ ์‹ค์ œ ๊ฒŒ์‹œ๊ธ€ ID๋กœ ์น˜ํ™˜
sequenceDiagram
  participant Client
  participant Server
  participant AWS
  Client->>Server: Image Upload Req
  Server->>AWS: Image Upload in S3
  Server->>Client: Return Image URL
  Client->>Server: Save Board Req
  Server->>AWS: Change Folder Name
Loading

ํšŒ์›๊ฐ€์ž…์‹œ ์ด๋ฉ”์ผ ์ธ์ฆ ๊ตฌํ˜„ํ•˜๊ธฐ

nodemailer + gmail์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฉ”์ผ ์ธ์ฆ์„ ๊ตฌํ˜„์ค‘ ์•„๋ž˜ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

  • 2022.05.30 ์ดํ›„ OAuth2.0 ๋ฏธ์‚ฌ์šฉ์‹œ Gmail API ์‚ฌ์šฉ ๋ถˆ๊ฐ€
  • ๊ณต์‹๋ฌธ์„œ์—์„œ๋Š” OAuth ์‚ฌ์šฉ๋ฐฉ๋ฒ•๊ณผ ๊ด€๋ จ๋œ ์ž์„ธํ•œ ๋ฐฉ๋ฒ•์ด ๋‚˜์™€์žˆ์ง€ ์•Š์•˜์Œ

์œ„ ์ œ์•ฝ์‚ฌํ•ญ์œผ๋กœ ์ธํ•ด Gmail API์˜ OAuth์™€ nodemailer๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ธ์ฆ๋ฉ”์ผ ๋ฐœ์†ก๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ๊ณผ์ •์€ Tistory ๋ธ”๋กœ๊ทธ์— ์ •๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.

JWT Access Token์˜ ์งง์€ ์ˆ˜๋ช…์œผ๋กœ ์ธํ•œ ์œ ์ €์˜ ๋ถˆํŽธํ•œ ๊ฒฝํ—˜๊ฐœ์„ 

๊ธฐ๋ณธ์ ์œผ๋กœ Access Token์˜ ๊ฒฝ์šฐ localStorage๋“ฑ ํด๋ผ์ด์–ธํŠธ(๋ธŒ๋ผ์šฐ์ €)์˜ ์ €์žฅ๊ณต๊ฐ„์—์„œ ๋ณด๊ด€ํ•ฉ๋‹ˆ๋‹ค.
์ด์— ๋”ฐ๋ผ์„œ ์ˆ˜๋ช…์ด ๊ธธ๋ฉด ํƒˆ์ทจ๋‹นํ–ˆ์„๋•Œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
JWT Refresh Token์„ ํ™œ์šฉํ•˜์—ฌ ์œ ์ €์˜ ์‚ฌ์šฉ๊ฒฝํ—˜์ด ๋ถˆํŽธํ•˜์ง€ ์•Š๋„๋ก ๊ฐœ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค.

  • ํ† ํฐ์˜ ์œ ํšจ์‹œ๊ฐ„์˜ ๊ฒฝ์šฐ Access Token์€ 15๋ถ„, Refresh Token์€ 10์ผ๋กœ ์ง€์ •
  • Refresh Token์€ httpOnly, Secure ์˜ต์…˜์œผ๋กœ ์ฟ ํ‚ค์— ์ €์žฅ
  • ์„œ๋ฒ„์—์„œ 401 Unauthorized ์—๋Ÿฌ ๋ฐ˜ํ™˜์‹œ Refresh Token์„ ํ™œ์šฉํ•œ ์žฌ์š”์ฒญ ๋ฐ Access Token ์žฌ๋ฐœ๊ธ‰
res.cookie('refreshToken', refreshToken, { httpOnly: true, path: '/', secure: true });


์กฐํšŒ์ˆ˜ ์ฆ๊ฐ€ API์˜ ๋ฐ˜๋ณต์ ์ธ ํ˜ธ์ถœ ๋ฌธ์ œํ•ด๊ฒฐ

๊ฒŒ์‹œ๊ธ€ ์ƒ์„ธ๋ณด๊ธฐ๋ฅผ ๋ˆ„๋ฅด๊ฒŒ๋˜๋ฉด ์กฐํšŒ์ˆ˜๋ฅผ ์ฆ๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด API๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
์ด๋•Œ ์ด๋ฏธ ์กฐํšŒํ•œ ๊ฒŒ์‹œ๋ฌผ๋„ ๊ณ„์† API ํ˜ธ์ถœ์ด ๋“ค์–ด์˜ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
์‚ฌ์šฉ์ž๊ฐ€ ์•…์˜์ ์œผ๋กœ ์ƒˆ๋กœ๊ณ ์นจ ํ…Œ๋Ÿฌ๋ฅผ ํ•˜๋Š”๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์ฟ ํ‚ค๋ฅผ ์„ค์ •ํ•˜์—ฌ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค.

  • ๊ฒŒ์‹œ๊ธ€ ์ƒ์„ธ๋ณด๊ธฐ ํŽ˜์ด์ง€ ์ ‘์†์‹œ 24์‹œ๊ฐ„๋™์•ˆ ์œ ์ง€๋˜๋Š” ์ฟ ํ‚ค ์ƒ์„ฑ
  • ๊ฒŒ์‹œ๊ธ€ ์ƒ์„ธ๋ณด๊ธฐ ํŽ˜์ด์ง€ ์ ‘์†์‹œ ์ฟ ํ‚ค ์—ฌ๋ถ€์— ๋”ฐ๋ผ ์กฐํšŒ์ˆ˜ ํ˜ธ์ถœ์—ฌ๋ถ€ ๊ฒฐ์ •



๐Ÿšซ ๊ฐœ์„  ๋ฐ ๊ตฌํ˜„์ด ํ•„์š”ํ•œ ๋ฌธ์ œ๋“ค

๋งŽ์€ ์–‘์˜ ๊ฒŒ์‹œ๊ธ€ ๋กœ๋”ฉ์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ๋ฒˆ์— ๋ Œ๋”๋งํ•˜๋Š” ๋ฌธ์ œ

๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก ๋˜๋Š” ๊ฒ€์ƒ‰๊ธฐ๋Šฅ ์‚ฌ์šฉ์‹œ DB์— ์กด์žฌํ•˜๋Š” ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ๋ฒˆ์— ์‘๋‹ต๋ฐ›์Šต๋‹ˆ๋‹ค.
์•ฝ 1000๊ฐœ์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์กด์žฌํ•  ๊ฒฝ์šฐ ๋ Œ๋”๋ง์‹œ ๋งค์šฐ ๋ฒ„๋ฒ…์ด๊ฒŒ ๋˜๋ฉฐ ์œ ์ €์—๊ฒŒ๋Š” ์•ˆ์ข‹์€ ๊ฒฝํ—˜์œผ๋กœ ์™€๋‹ฟ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ์ƒ๊ฐ์ค‘์ธ ํ•ด๊ฒฐ๋ฐฉ์•ˆ์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ํด๋ผ์ด์–ธํŠธ : ๋ฌดํ•œ์Šคํฌ๋กค์„ ๊ตฌํ˜„ํ•˜์—ฌ ํŠน์ • ์‹œ์ ์— ์„œ๋ฒ„์— ๋ฐ์ดํ„ฐ ์š”์ฒญ
  • ์„œ๋ฒ„ : ์ฟผ๋ฆฌ์ŠคํŠธ๋ง์„ ํ†ตํ•ด ๋ฐ˜ํ™˜ํ•  ๋ฐ์ดํ„ฐ์˜ ๋ฒ”์œ„๋ฅผ ๋ฐ›๊ณ , ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ธก์—์„œ ํ•„ํ„ฐ๋ง์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ ๋ฐ˜ํ™˜

Swagger ๋ฌธ์„œ ๋ฐ์ดํ„ฐ๋กœ ์ธํ•ด ๊ธธ์–ด์ง€๋Š” ์ฝ”๋“œ

ํ˜„์žฌ๋Š” Controller์— ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฌธ์„œ์— ํ•„์š”ํ•œ ๋‚ด์šฉ์„ ์ •์˜ํ•ด๋‘” ์ƒํƒœ์ž…๋‹ˆ๋‹ค

ํ•˜์ง€๋งŒ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๋‚ด๋ถ€์— ๋ชจ๋“  ๋‚ด์šฉ์„ ์ •์˜ํ•  ๊ฒฝ์šฐ ์•„๋ž˜์™€ ๊ฐ™์ด ์ฝ”๋“œ๊ฐ€ ๋งค์šฐ ๊ธธ์–ด์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

  @ApiOperation({ summary: 'ํšŒ์›๊ฐ€์ž… API' })
  @ApiCreatedResponse({
    description: `ํšŒ์›๊ฐ€์ž… ์„ฑ๊ณต์‹œ 201 ์ฝ”๋“œ์™€ ์ƒ์„ฑ๋œ ์‚ฌ์šฉ์ž์˜ ์•„์ด๋”” ๋ฐ˜ํ™˜`,
    schema: {
      type: 'object',
      properties: { userId: { type: 'string' } },
    },
  })
  @ApiBadRequestResponse({
    description: `
      ์ด๋ฉ”์ผ ํ˜•์‹์ด ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์„๊ฒฝ์šฐ - invalid_email
      ๋น„๋ฐ€๋ฒˆํ˜ธ ํ˜•์‹์ด ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์„๊ฒฝ์šฐ - invalid_password
      ๋‹‰๋„ค์ž„ ํ˜•์‹์ด ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์„๊ฒฝ์šฐ - invalid_nickname
      ์ค‘๋ณต๋œ ์ด๋ฉ”์ผ์ธ ๊ฒฝ์šฐ - exist_email
      ์ค‘๋ณต๋œ ๋‹‰๋„ค์ž„์ธ ๊ฒฝ์šฐ - exist_nickname`,
    schema: {
      type: 'object',
      properties: {
        statusCode: { type: 'number' },
        message: {
          example: 'invalid_email, invalid_password, invalid_nickname, exist_email, exist_nickname',
        },
      },
    },
  })
  @UsePipes(ValidationPipe)
  @Post('register')
  async register(@Body() registerDto: RegisterDto) {
    const userId = await this.authService.register(registerDto);
    return { userId };
  }

Swagger ๋ฌธ์„œ์— ํ•„์š”ํ•œ ๋‚ด์šฉ์€ ์™ธ๋ถ€ํŒŒ์ผ๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ๊ฐœ์„ ํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.


23.04.28 - ๋ชจ๋“ˆ ๋‚ด module.swagger.ts ์ƒ์„ฑ ๋ฐ applyDecorator๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ถ„๋ฆฌ์™„๋ฃŒ

  @ApiRegister('ํšŒ์›๊ฐ€์ž… API')
  @UsePipes(ValidationPipe)
  @Post('register')
  async register(@Body() registerDto: RegisterDto) {
    const userId = await this.authService.register(registerDto);
    return { userId };
  }


์ฒ˜์Œ ๋„์ž…ํ•˜๊ณ  ๊ฒฝํ—˜ํ•œ ๊ธฐ์ˆ ๊ณผ ๊ฐœ๋…๋“ค์ด ๋“ค์ด ๋งค์šฐ ๋งŽ์•˜์Šต๋‹ˆ๋‹ค.
TDD ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์„œ CI/CD, AWS, ์ƒˆ๋กœ์šด ํ”„๋ ˆ์ž„์›Œํฌ/๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋“ฑ..
์ƒˆ๋กœ์šด๊ฑธ ๋ฐฐ์šธ๋•Œ๋งˆ๋‹ค ๊ณ„์†ํ•ด์„œ ๊ธฐ๋กํ•˜๊ณ  ๊พธ์ค€ํ•˜๊ฒŒ ๋…ธ๋ ฅํ–ˆ์Šต๋‹ˆ๋‹ค.
์ฒ˜์Œ ๋งˆ์ฃผํ•˜๋Š” ๋ฌธ์ œ๋”๋ผ๋„ ๊พธ์ค€ํžˆ ๋…ธ๋ ฅํ•˜๋ฉด ํ•ด๊ฒฐํ• ์ˆ˜ ์žˆ๋‹ค๋Š” ์ž์‹ ๊ฐ์„ ์–ป์„ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

About

Topics

Resources

Stars

38 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages