Skip to content

wlgks7460/Bobissue

Folders and files

NameName
Last commit message
Last commit date

Latest commit

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

Repository files navigation

๐Ÿฅ— ๋ฐฅ์ด์Šˆ(Bobissue)

๐Ÿฅ— ํ”„๋กœ์ ํŠธ ๊ฐœ์š”

๐Ÿš€ ํ”„๋กœ์ ํŠธ ์†Œ๊ฐœ

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

๐ŸŽฏ ํ”„๋กœ์ ํŠธ ๊ธฐํš ๋ฐฐ๊ฒฝ

๐ŸŒฟ ๊ฑด๊ฐ•ํ•œ ์‹๋‹จ๊ด€๋ฆฌ ํ•„์š”์„ฑ

  • ๋งŒ์„ฑ ์งˆํ™˜ ์˜ˆ๋ฐฉ ์ค‘์š”์„ฑ ์ธ์‹
  • ์˜ฌ๋ฐ”๋ฅธ ์˜์–‘ ์„ญ์ทจ์˜ ํ•„์š”์„ฑ
  • ๋‹ค์ด์–ดํŠธ ๋ฐ ๊ฑด๊ฐ•์‹์— ๋Œ€ํ•œ ๊ด€์‹ฌ๋„ ์ง€์†์  ์ƒ์Šน
  • ๊ฑด๊ฐ•ํ•œ ์ƒํ™œ์Šต๊ด€ ํ˜•์„ฑ ์š•๊ตฌ

๐Ÿด ๋งž์ถคํ˜• ์‹๋‹จ ์ˆ˜์š” ์ฆ๊ฐ€

  • ๊ฐœ์ธ ๊ฑด๊ฐ•๋ฐ์ดํ„ฐ ์ €์žฅ ๋ฐ ํ™œ์šฉ ์ฆ๊ฐ€
  • ๋‹ค์–‘ํ•œ ์‹๋‹จ ์š”๊ตฌ์‚ฌํ•ญ ์กด์žฌ
  • ํŽธ์˜์„ฑ๊ณผ ํšจ์œจ์„ฑ ๋™์‹œ ์ถ”๊ตฌ

๐Ÿ“ˆ ์˜จ๋ผ์ธ ์‹ํ’ˆ ์‹œ์žฅ ์„ฑ์žฅ

  • ์ฝ”๋กœ๋‚˜ 19๋กœ ์ธํ•œ ๋น„๋Œ€๋ฉด ์„ ํ˜ธ
  • ์‹ ์„ ์‹ํ’ˆ ์˜จ๋ผ์ธ ๊ตฌ๋งค ์ฆ๊ฐ€
  • MZ ์„ธ๋Œ€์˜ ์˜จ๋ผ์ธ ์‡ผํ•‘ ์„ ํ˜ธ
  • ๊ฐ„ํŽธ์‹ ๋ฐ ๋ฐ€ํ‚คํŠธ ์‹œ์žฅ ํ™•๋Œ€

โš ๏ธ ๋ฌธ์ œ์ 

๐Ÿ” ๊ฐœ์ธํ™” ๋ถ€์กฑ

  • ๊ธฐ์กด ์‹๋‹จ ๊ด€๋ฆฌ ์„œ๋น„์Šค์˜ ํ•œ๊ณ„
  • ์‡ผํ•‘๋ชฐ๊ณผ์˜ ๋ถ„๋ฆฌ๋กœ ํšจ์œจ์„ฑ ๋‚ฎ์€ ๊ฒฝ์šฐ ๋งŽ์Œ
    • ์ฆ‰, ์‹๋‹จ์„ ์งœ๊ณ  ํ™œ์šฉํ•ด๋ณด๊ณ  ์‹ถ์ง€๋งŒ ์‹œ๊ฐ„์ด ์—†๋Š” ๊ฒฝ์šฐ ์ง์ ‘ ์Œ์‹์„ ๊ณ ๋ฅด๊ณ  ์ฃผ๋ฌธํ•˜๊ณ  ๊ธฐ๋กํ•˜๋Š” ์ „๊ณผ์ •์ด ์˜ค๋ž˜ ์†Œ์š”๋˜๊ณ  ๋น„ํšจ์œจ์ .

๐Ÿ•’ ์ง€์†์„ฑ ๋ฌธ์ œ

  • ๋‹จ๊ธฐ์ ์ธ ์‹๋‹จ ๊ด€๋ฆฌ
  • ๋™๊ธฐ๋ถ€์—ฌ ์š”์†Œ ๋ถ€์กฑ
  • ์‚ฌ์šฉ์ž ์ดํƒˆ๋ฅ  ๋†’์Œ

๐Ÿ’ก ์„œ๋น„์Šค ํ•ด๊ฒฐ๋ฐฉ์•ˆ

๐Ÿงบ ์‡ผํ•‘๋ชฐ ํ†ตํ•ฉ

  • ์‹๋‹จ๊ณผ ์‡ผํ•‘ ์—ฐ๊ณ„
  • ํŽธ๋ฆฌํ•œ ๊ตฌ๋งค ๊ฒฝํ—˜
  • ์‹ ์„ ์‹ํ’ˆ ์ œ๊ณต
  • ์‹œ๊ฐ„ ์ ˆ์•ฝ ๊ฐ€๋Šฅ

๐Ÿ”— ์›์Šคํ†ฑ ์†”๋ฃจ์…˜

  • ์‹๋‹จ ๊ณ„ํš๋ถ€ํ„ฐ ๊ตฌ๋งค๊นŒ์ง€
  • ํ•œ ํ”Œ๋žซํผ์—์„œ ํ•ด๊ฒฐ
  • ์‚ฌ์šฉ์ž ํŽธ์˜์„ฑ ์ฆ๋Œ€
  • ํ†ตํ•ฉ ์„œ๋น„์Šค ์ œ๊ณต

๐Ÿ”‘ ์ฃผ์š” ๊ธฐ๋Šฅ ๋ฐ ํ•ต์‹ฌ ์„œ๋น„์Šค

๐Ÿ›’ ์‡ผํ•‘๋ชฐ

  • ์‹์žฌ๋ฃŒ ํŒ๋งค
  • ๊ฑด๊ฐ•์‹ํ’ˆ ์ œ๊ณต
  • ๋งž์ถคํ˜• ์ƒํ’ˆ ์ถ”์ฒœ
  • ํŽธ๋ฆฌํ•œ ๊ตฌ๋งค ๊ฒฝํ—˜

๐ŸŽฅ ๋ผ์ด๋ธŒ ์ปค๋จธ์Šค

  • ์‹ค์‹œ๊ฐ„ ์ƒํ’ˆ ์†Œ๊ฐœ
  • ์ฆ‰๊ฐ์ ์ธ ์งˆ์˜์‘๋‹ต
  • ํŠน๋ณ„ ํ• ์ธ ํ˜œํƒ

๐Ÿฅ— ์‹๋‹จ ๊ด€๋ฆฌ

  • ๊ฐœ์ธํ™”๋œ ์‹๋‹จ ๊ด€๋ฆฌ
  • ์นผ๋กœ๋ฆฌ ๋ฐ ์˜์–‘ ๊ณ„์‚ฐ
  • ์‹๋‹จ ๊ธฐ๋ก ๋ฐ ๋ ˆ์‹œํ”ผ ๊ณต์œ 
  • ์‡ผํ•‘๋ชฐ ์—ฐ๊ณ„ ์‹๋‹จ ๊ด€๋ฆฌ ๋ฐ ์ฆ‰์‹œ ์ฃผ๋ฌธ


๐Ÿฅ— ๊ฐœ๋ฐœ ํ™˜๊ฒฝ

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

ํ•ญ๋ชฉ ๊ธฐ์ˆ 
๊ฐœ๋ฐœ ํ™˜๊ฒฝ Visual Studio Code
ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด JavaScript
๋นŒ๋“œ ๋„๊ตฌ Vite
ํ”„๋ ˆ์ž„์›Œํฌ React
์ƒํƒœ ๊ด€๋ฆฌ Redux
CSS ํ”„๋ ˆ์ž„์›Œํฌ Tailwind CSS
์ธ์ฆ/๋ณด์•ˆ OAuth

๐Ÿ’ป ๋ฐฑ์—”๋“œ

ํ•ญ๋ชฉ ๊ธฐ์ˆ 
ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด Java
๊ฐœ๋ฐœ ํ™˜๊ฒฝ IntelliJ IDEA
๋นŒ๋“œ ๋„๊ตฌ Gradle
ํ”„๋ ˆ์ž„์›Œํฌ Spring Boot
๋ณด์•ˆ Spring Security JWT

โš™๏ธ ๊ณตํ†ต

ํ•ญ๋ชฉ ๊ธฐ์ˆ 
ํ˜•์ƒ ๊ด€๋ฆฌ Git GitLab
ํ˜‘์—… Notion JIRA
๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค MySQL Redis MongoDB ElasticSearch
์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜ Mattermost
๋ฐฐํฌ Jenkins Docker Nginx


๐Ÿฅ— ์š”๊ตฌ์‚ฌํ•ญ ๋ถ„์„(๊ธฐ๋Šฅ ๋ช…์„ธ์„œ)

๐Ÿ‘ค ์ด์šฉ์ž

Details
๊ถŒํ•œ ๋Œ€๋ถ„๋ฅ˜ ์ค‘๋ถ„๋ฅ˜ ์†Œ๋ถ„๋ฅ˜ ์„ค๋ช…
์ด์šฉ์ž 1. ํšŒ์›๊ฐ€์ž… 1-1. ํšŒ์›๊ฐ€์ž… ํ•„์ˆ˜: ์•„์ด๋””, ๋น„๋ฐ€๋ฒˆํ˜ธ, ์ด๋ฆ„, ์ฃผ์†Œ, ๋‹‰๋„ค์ž„, ์ „ํ™”, ์ด๋ฉ”์ผ, ์ƒ๋…„์›”์ผ, ์„ฑ๋ณ„
๋™์˜: ์ด์šฉ์•ฝ๊ด€, ๊ฐœ์ธ์ •๋ณด ์ˆ˜์ง‘ ๋ฐ ์ด์šฉ
์„ ํƒ: ์ˆ˜์‹  ๋™์˜, ์‚ฌ์ง„
1-2. ์†Œ์…œ ํšŒ์›๊ฐ€์ž…
2. ๋กœ๊ทธ์ธ 2-1. ๋กœ๊ทธ์ธ ์•„์ด๋”” & ๋น„๋ฐ€๋ฒˆํ˜ธ ์ž…๋ ฅ ํ›„ ๋กœ๊ทธ์ธ
2-2. ์†Œ์…œ ๋กœ๊ทธ์ธ ๋„ค์ด๋ฒ„, ์นด์นด์˜ค ๊ฐ„ํŽธ ๋กœ๊ทธ์ธ ์ง€์›
2-3. ๋น„๋ฐ€๋ฒˆํ˜ธ ์ฐพ๊ธฐ
3. ๋กœ๊ทธ์•„์›ƒ
4. ํšŒ์› ๋“ฑ๊ธ‰ 4-1. ๋“ฑ๊ธ‰ ํ™•์ธ ๊ตฌ๋งค ๊ธˆ์•ก์— ๋”ฐ๋ฅธ ํฌ์ธํŠธ ์ ๋ฆฝ ๋ฐ ๋“ฑ๊ธ‰์ œ ์šด์˜
5. ๋„ค๋น„๊ฒŒ์ด์…˜๋ฐ” 5-1. ์นดํ…Œ๊ณ ๋ฆฌ 5-1-1. ์ข…๋ฅ˜๋ณ„ ๋‹ญ๊ณ ๊ธฐ, ์†Œ๊ณ ๊ธฐ/๋ผ์ง€๊ณ ๊ธฐ, ๊น€๋ฐฅ/๋„์‹œ๋ฝ/๋ณถ์Œ๋ฐฅ, ์ƒ๋Ÿฌ๋“œ/๊ณผ์ผ ๋“ฑ
5-1-2. ๋ชฉ์ ๋ณ„ ๊ฐ„ํŽธ์‹, ๋‹ค์ด์–ดํŠธ, ์˜์–‘์‹, ๋ฒŒํฌ์—…
6. ๋ผ์ด๋ธŒ ์ปค๋จธ์Šค 6-1. ๋ผ์ด๋ธŒ ์ผ์ • ๋ณด๊ธฐ ๋ผ์ด๋ธŒ ์ปค๋จธ์Šค ๋ฐฉ์†ก ๋ฆฌ์ŠคํŠธ ํ‘œ์‹œ
6-2. ๋ผ์ด๋ธŒ ์‹œ์ฒญ ๋ผ์ด๋ธŒ ๋ฐฉ์†ก ์‹œ์ฒญ ๋ฐ ์ฑ„ํŒ… ๊ฐ€๋Šฅ
7. ์ƒํ’ˆ ์กฐํšŒ 7-1. ์ƒํ’ˆ ๋ชฉ๋ก ์ƒํ’ˆ ์ด๋ฏธ์ง€, ์ด๋ฆ„, ๊ฐ€๊ฒฉ ๋“ฑ ์ •๋ณด ์กฐํšŒ
8. ์ƒํ’ˆ ์ƒ์„ธ 8-1. ์ƒํ’ˆ ์ƒ์„ธ์ •๋ณด ์ƒํ’ˆ ์„ค๋ช…, ์˜์–‘์„ฑ๋ถ„, ํŒ๋งค์ž ์ •๋ณด ๋“ฑ
8-2. ์ƒํ’ˆ ์ฐœ 8-2-1. ์ฐœํ•˜๊ธฐ ๋งˆ์ดํŽ˜์ด์ง€์—์„œ ํ™•์ธ ๊ฐ€๋Šฅ
9. ์žฅ๋ฐ”๊ตฌ๋‹ˆ 9-1. ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ชฉ๋ก 9-1-1. ์ƒํ’ˆ ์ •๋ณด ์กฐํšŒ ์ˆ˜๋Ÿ‰, ์˜ต์…˜ ์ˆ˜์ • ๋ฐ ์‚ญ์ œ ๊ฐ€๋Šฅ
10. ๊ฒฐ์ œ 10-1. ๋ฐฐ์†ก์ง€ 10-1-1. ๋ฐฐ์†ก์ง€ ์„ ํƒ ๊ธฐ๋ณธ ๋ฐฐ์†ก์ง€ ์„ค์ • ๊ฐ€๋Šฅ
10-2. ๊ฒฐ์ œ ๊ธˆ์•ก 10-2-1. ํ• ์ธ ์ฟ ํฐ ๊ด€๋ฆฌ์ž ๋ฐœ๊ธ‰ ์ฟ ํฐ ์ ์šฉ ๊ฐ€๋Šฅ
10-5. ๊ฒฐ์ œ ๊ฒฐ์ œ API ํ˜ธ์ถœ
11. ๋งˆ์ดํŽ˜์ด์ง€ 11-1. ์ฃผ๋ฌธ ๋ชฉ๋ก 11-1-1. ์ฃผ๋ฌธ ๋‚ด์—ญ ์กฐํšŒ ์ฃผ๋ฌธ ๊ธฐ๊ฐ„ ์„ ํƒ ๋ฐ ์ƒํ’ˆ ๊ฒ€์ƒ‰ ๊ฐ€๋Šฅ
12. ๊ณ ๊ฐ์„ผํ„ฐ 12-1. FAQ ์ž์ฃผ ๋ฌป๋Š” ์งˆ๋ฌธ ์นดํ…Œ๊ณ ๋ฆฌ ์ œ๊ณต
13. ๋ ˆ์‹œํ”ผ 13-1. ๋ ˆ์‹œํ”ผ ์ƒ์„ฑ 13-1-1. ๋ ˆ์‹œํ”ผ ์ž‘์„ฑ ๋ ˆ์‹œํ”ผ๋ช…, ์‹œ๊ฐ„, ๋ฐฉ๋ฒ• ๊ธฐ์ž…

๐Ÿช ํŒ๋งค์ž

Details
๊ถŒํ•œ ๋Œ€๋ถ„๋ฅ˜ ์ค‘๋ถ„๋ฅ˜ ์†Œ๋ถ„๋ฅ˜ ์„ค๋ช…
ํŒ๋งค์ž 1. ํšŒ์›๊ฐ€์ž… 1-1. ํšŒ์› ๊ฐ€์ž… ํšŒ์›๊ฐ€์ž… ์œ ํ˜•: ์‚ฌ์—…์ž ์ „์šฉ
2. ๋กœ๊ทธ์ธ 2-1. ๋กœ๊ทธ์ธ ํŒ๋งค์ž๋Š” ์†Œ์…œ ๋กœ๊ทธ์ธ ๋ถˆ๊ฐ€
4. ํŒ๋งค์ž ํŽ˜์ด์ง€ 4-1. ์ƒํ’ˆ ๋ชฉ๋ก ๊ด€๋ฆฌ 4-1-1. ์ƒํ’ˆ ์ •๋ณด ๋ชฉ๋ก ์กฐํšŒ ์ƒํ’ˆ๋ช…, ๊ฐ€๊ฒฉ, ์ƒ์„ธ์„ค๋ช…, ์žฌ๊ณ  ํฌํ•จ
4-2. ์ƒํ’ˆ ๊ด€๋ฆฌ 4-2-1. ์ƒํ’ˆ ์ •๋ณด ๋“ฑ๋ก ์ƒํ’ˆ๋ช…, ๊ฐ€๊ฒฉ, ์žฌ๊ณ , ํ• ์ธ ์„ค์ • ๊ฐ€๋Šฅ
4-3. ์ฃผ๋ฌธ/๋ฐฐ์†ก ๊ด€๋ฆฌ 4-3-1. ์ฃผ๋ฌธ ๋ชฉ๋ก ์กฐํšŒ ๊ตฌ๋งค์ž์˜ ๋ฐฐ์†ก ์ฒ˜๋ฆฌ ๋ชฉ๋ก ์กฐํšŒ
4-3-2. ์ถœ๊ณ  ๊ด€๋ฆฌ ์ด์šฉ์ž ๊ตฌ๋งค ์ƒํ’ˆ ๋ฐฐ์†ก
4-4. ์ •์‚ฐ 4-4-1. ์ •์‚ฐ ์กฐํšŒ ์ •์‚ฐ ๊ธˆ์•ก ๋ฐ ๋‚ ์งœ ํ™•์ธ ๊ฐ€๋Šฅ
4-5. ํŒ๋งค์ž ์ •๋ณด ๊ด€๋ฆฌ 4-5-1. ํŒ๋งค์ž ์ •๋ณด ์กฐํšŒ ํŒ๋งค์ž ๋“ฑ๊ธ‰, ํŒ๋งค ๋‚ด์—ญ ํ™•์ธ
5. ๊ณ ๊ฐ ๊ด€๋ฆฌ 5-1. 1:1 ๋ฌธ์˜ ์‘๋Œ€ 5-1-1. ๋ฌธ์˜ ์กฐํšŒ ์ด์šฉ์ž ๋ฌธ์˜ ๋ชฉ๋ก ์กฐํšŒ ๋ฐ ์ƒ์„ธ ๋‹ต๋ณ€
6. ๋ผ์ด๋ธŒ ์ปค๋จธ์Šค 6-1. ๋ผ์ด๋ธŒ ์‹ ์ฒญํ•˜๊ธฐ ๊ด€๋ฆฌ์ž์—๊ฒŒ ๋ผ์ด๋ธŒ ๋ฐฉ์†ก ์‹ ์ฒญ ๊ฐ€๋Šฅ
7. ํŒ๋งค ํ†ต๊ณ„ 7-1. ํŒ๋งค ์„ฑ๊ณผ ์กฐํšŒ ๊ฒฐ์ œ ๊ธˆ์•ก ๋ฐ ํ™˜๋ถˆ ํ˜„ํ™ฉ ์ผ๋ณ„ ๋ถ„์„
9. ๋ ˆ์‹œํ”ผ 9-1. ๋ ˆ์‹œํ”ผ ์ƒ์„ฑ 9-1-1. ๋ ˆ์‹œํ”ผ ์ž‘์„ฑ ๋ ˆ์‹œํ”ผ๋ช…, ์‹œ๊ฐ„, ๋ฐฉ๋ฒ• ์ž…๋ ฅ

๐Ÿ‘ฎ ๊ด€๋ฆฌ์ž

Details
๊ถŒํ•œ ๋Œ€๋ถ„๋ฅ˜ ์ค‘๋ถ„๋ฅ˜ ์†Œ๋ถ„๋ฅ˜ ์„ค๋ช…
๊ด€๋ฆฌ์ž 1. ๋กœ๊ทธ์ธ/๋กœ๊ทธ์•„์›ƒ
2. ์ผ๋ฐ˜ ํšŒ์› ๊ด€๋ฆฌ 2-1. ํšŒ์› ๋ชฉ๋ก ์กฐํšŒ ์ „์ฒด ํšŒ์› ๋ฐ ํŠน์ • ํšŒ์› ์กฐํšŒ
2-2. ํšŒ์› ์ƒ์„ธ ์กฐํšŒ 2-2-1. ํšŒ์› ์ •๋ณด ์กฐํšŒ ๊ฐœ์ธ์ •๋ณด ๋ฐ ๋“ฑ๊ธ‰ ์กฐํšŒ
3. ํŒ๋งค์ž ํšŒ์› ๊ด€๋ฆฌ 3-1. ํŒ๋งค์ž ๋ชฉ๋ก ์กฐํšŒ 3-1-1. ์ „์ฒด ํŒ๋งค์ž ์กฐํšŒ
3-2. ํŒ๋งค์ž ์ƒ์„ธ ์กฐํšŒ 3-2-1. ํŒ๋งค์ž ์‹ ์ฒญ ์กฐํšŒ ํŒ๋งค์ž๊ฐ€ ์ƒํ’ˆ ํŒ๋งค ์‹ ์ฒญํ•œ ๋ชฉ๋ก
3-2-2. ํŒ๋งค์ž ์ •๋ณด ์กฐํšŒ ํ•ด๋‹น ํšŒ์‚ฌ์˜ ๊ณ„์ • ์ˆ˜, ํ™œ๋™ ๋‚ด์—ญ, ํŒ๋งค ์ œํ’ˆ ๋“ฑ
3-2-3. ํŒ๋งค์ž ํ™œ์„ฑํ™” ๋น„ํ™œ์„ฑํ™”๋œ ํŒ๋งค์ž ๊ณ„์ • ํ™œ์„ฑํ™”
4. ๋ผ์ด๋ธŒ ์ปค๋จธ์Šค 4-1. ๋ผ์ด๋ธŒ ์‹œ๊ฐ„ํ‘œ ๊ด€๋ฆฌ 4-1-1. ๋ผ์ด๋ธŒ ์‹ ์ฒญ๋ฐ›๊ธฐ ํŒ๋งค์ž๊ฐ€ ์‹ ์ฒญํ•œ ๋ผ์ด๋ธŒ ๊ด€๋ฆฌ
5. ์ปจํ…์ธ  ๊ด€๋ฆฌ 5-1. ์ฟ ํฐ ๊ด€๋ฆฌ 5-1-1. ์ฟ ํฐ ํ˜„ํ™ฉ ์กฐํšŒ ์‚ฌ์ดํŠธ ๋‚ด ๋ชจ๋“  ์ฟ ํฐ ์กฐํšŒ
5-2. ํ™”๋ฉด ๊ด€๋ฆฌ 5-2-1. ์ด๋ฒคํŠธ ๋ฐฐ๋„ˆ ๋“ฑ๋ก ์ด๋ฒคํŠธ ๋ฐฐ๋„ˆ ์ƒ์„ฑ ๋ฐ ๊ด€๋ฆฌ
6. CS ๊ด€๋ฆฌ 6-1. ์•Œ๋ฆผ ๊ด€๋ฆฌ 6-1-1. ์•Œ๋ฆผ ๋ณด๋‚ด๊ธฐ ์ „์ฒด ๋ฐ ๊ฐœ๋ณ„ ์•Œ๋ฆผ ์ „์†ก ๊ฐ€๋Šฅ
6-2. ๊ณ ๊ฐ ์„ผํ„ฐ ๊ด€๋ฆฌ 6-2-1. ๋ฌธ์˜ ์กฐํšŒ ์ด์šฉ์ž ๋ฌธ์˜ ๋‚ด์šฉ ํ™•์ธ
6-3. ๊ณต์ง€์‚ฌํ•ญ ๊ด€๋ฆฌ 6-3-1. ๊ณต์ง€์‚ฌํ•ญ ์กฐํšŒ ์ด์šฉ์ž/ํŒ๋งค์ž๋ณ„ ๊ณต์ง€ ๊ตฌ๋ถ„ ๊ฐ€๋Šฅ


๐Ÿ—“๏ธ WBS

BobIssue WBS ๋ณด๊ธฐ [WBS ๋ณด๊ธฐ](./exec/image/WBS.pdf)


๐Ÿ—ƒ๏ธ ERD

BobIssue ERD ๋ณด๊ธฐ ๋ฐฅ์ด์ŠˆERD


๐Ÿ“ฑ ํ™”๋ฉด์„ค๊ณ„์„œ

์ด์šฉ์ž Wireframe ๋ณด๊ธฐ ์ด์šฉ์ž Wireframe

ํŒ๋งค์ž Wireframe ๋ณด๊ธฐ ํŒ๋งค์ž Wireframe

๊ด€๋ฆฌ์ž Wireframe ๋ณด๊ธฐ ๊ด€๋ฆฌ์ž Wireframe


๐Ÿ—๏ธ ์•„ํ‚คํ…์ฒ˜ ์„ค๊ณ„๋„

์•„ํ‚คํ…์ฒ˜ ์„ค๊ณ„๋„ ๋ณด๊ธฐ ๋ฐฅ์ด์Šˆ๋ฐฐํฌ

๐ŸŽฅ API ์—ฐ๋™๊ทœ๊ฒฉ์„œ

API ์—ฐ๋™๊ทœ๊ฒฉ์„œ ๋ณด๊ธฐ [API ๋ช…์„ธ์„œ ๋ณด๊ธฐ](./exec/image/API.pdf)


โš’๏ธ ์ค‘์  ๊ธฐ์ˆ 

Querydsl

QueryDSL

๊ฐœ๋…

  • ํƒ€์ž… ์•ˆ์ „ํ•œ SQL ์ฟผ๋ฆฌ ๋นŒ๋”

    • ์ปดํŒŒ์ผ ์‹œ์ ์— ์˜ค๋ฅ˜๋ฅผ ์žก์•„๋‚ผ ์ˆ˜ ์žˆ์–ด ์•ˆ์ •์ 
    • IDE์˜ ์ž๋™์™„์„ฑ ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์–ด ๊ฐœ๋ฐœ์ด ์ˆ˜์›”ํ•จ
    • ๋™์  ์ฟผ๋ฆฌ ์ž‘์„ฑ์ด ๋งค์šฐ ํŽธ๋ฆฌํ•จ
  • ์‹ค๋ฌด์  ์ด์ 

    • ์ฟผ๋ฆฌ ์กฐ๊ฑด๋“ค์„ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฌ์›€
    • ์ฝ”๋“œ ๊ธฐ๋ฐ˜์ด๋ผ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์šฉ์ดํ•จ
    • ๋ณต์žกํ•œ ์„œ๋ธŒ์ฟผ๋ฆฌ๋‚˜ ์กฐ์ธ๋„ ๊น”๋”ํ•˜๊ฒŒ ํ‘œํ˜„ ๊ฐ€๋Šฅ
    • ๋ฉ”์„œ๋“œ ์ฒด์ด๋‹์œผ๋กœ ์ง๊ด€์ ์ธ ์ฟผ๋ฆฌ ์ž‘์„ฑ์ด ๊ฐ€๋Šฅํ•จ
  • ์ฃผ์˜ํ•ด์•ผ ํ•  ์ 

    • ์‹คํ–‰๋˜๋Š” SQL์„ ํ™•์ธํ•˜๋ฉฐ ์„ฑ๋Šฅ์„ ๊ณ ๋ คํ•ด์•ผ ํ•จ
    • ๊ธฐ๋ณธ์ ์ธ SQL ์ง€์‹์ด ๋ฐ˜๋“œ์‹œ ํ•„์š”ํ•จ

JPQL๊ณผ ๋น„๊ตํ–ˆ์„ ๋•Œ์˜ ์žฅ์ 

  • ๋ณต์žกํ•œ ์—ฐ์‚ฐ ๊ณผ์ •์—์„œ ๊ฐ€๋…์„ฑ์ด ๋” ๋†’์Œ
  • ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์šฉ์ดํ•จ
  • ์ปดํŒŒ์ผ ๋‹จ๊ณ„์—์„œ ์ฟผ๋ฆฌ ์˜ค๋ฅ˜๊ฐ€ ๊ฐ์ง€๋จ
  • ์นดํ…Œ๊ณ ๋ฆฌ ์ˆ˜๊ฐ€ ๋งŽ๊ณ  ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ๊ฐ€ ๋‹ค์–‘ํ•œ ์‡ผํ•‘๋ชฐ์˜ ํŠน์„ฑ์— ์ ํ•ฉํ•จ
  • ๋ณต์žกํ•œ ํ•„ํ„ฐ๋ง ์กฐ๊ฑด์ด๋‚˜ ๋กœ์ง์„ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ

ํ”„๋กœ์ ํŠธ์—์„œ QueryDSL์„ ์‚ฌ์šฉํ•œ ์ด์œ 

  1. ๋ณต์žกํ•œ ์ถ”์ฒœ ์‹œ์Šคํ…œ ๊ตฌํ˜„

    • ์นดํ…Œ๊ณ ๋ฆฌ์™€ ์ธ๊ตฌํ†ต๊ณ„ํ•™์  ๋ฐ์ดํ„ฐ(์„ฑ๋ณ„, ์—ฐ๋ น๋Œ€)๋ฅผ ๊ฒฐํ•ฉํ•œ ๋งž์ถคํ˜• ์ƒํ’ˆ ์ถ”์ฒœ ์‹œ์Šคํ…œ ๊ตฌํ˜„
    • ๊ตฌ๋งค ์ด๋ ฅ ๊ธฐ๋ฐ˜ ํ˜‘์—… ํ•„ํ„ฐ๋ง ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ตฌํ˜„
    • ๋ ˆ์‹œํ”ผ ๊ธฐ๋ฐ˜ ์—ฐ๊ด€ ์ƒํ’ˆ ์ถ”์ฒœ ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ
  2. ๋‹ค์–‘ํ•œ ํ†ต๊ณ„ ๋ถ„์„ ์š”๊ตฌ์‚ฌํ•ญ ์ถฉ์กฑ

    • ์„ฑ๋ณ„์— ๋”ฐ๋ฅธ ์ƒํ’ˆ ์„ ํ˜ธ๋„ ๋ถ„์„ (getMalePreferredItems, getFemalePreferredItems)
    • ์žฌ๊ตฌ๋งค์œจ์ด ๋†’์€ ์ œํ’ˆ ๋ถ„์„ (getTopRepurchaseItems)
    • ๋ฒ ์ŠคํŠธ์…€๋Ÿฌ ์ƒํ’ˆ ๋ถ„์„ (getBestSellerItems)
  3. ์„œ๋ธŒ์ฟผ๋ฆฌ์™€ ๋ณต์žกํ•œ ์กฐ์ธ ์ฒ˜๋ฆฌ

    • ๋‹ค์–‘ํ•œ ์—”ํ‹ฐํ‹ฐ ๊ฐ„์˜ ๋ณต์žกํ•œ ๊ด€๊ณ„๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌ (์ƒํ’ˆ, ์ฃผ๋ฌธ, ์‚ฌ์šฉ์ž, ๋ฆฌ๋ทฐ ๋“ฑ)
    • ์ค‘์ฒฉ๋œ ์„œ๋ธŒ์ฟผ๋ฆฌ๋ฅผ ๊ฐ€๋…์„ฑ ์žˆ๊ฒŒ ๊ตฌํ˜„
  4. ๋™์  ํ‘œํ˜„์‹ ํ™œ์šฉ

    • ์‚ฌ์šฉ์ž ์—ฐ๋ น๋Œ€ ๊ณ„์‚ฐ์„ ์œ„ํ•œ ๋™์  ํ‘œํ˜„์‹ ์ƒ์„ฑ (ageGroupExpr)
    • ๋ณต์žกํ•œ ํ†ต๊ณ„ ์ˆ˜์‹์„ SQL ํ•จ์ˆ˜์™€ ๊ฒฐํ•ฉํ•˜์—ฌ ๊ตฌํ˜„

Querydsl ๋„์ž… ํšจ๊ณผ

  1. ํšจ์œจ์ ์ธ ์ฝ”๋“œ ๊ด€๋ฆฌ

    • ๋ณต์žกํ•œ ์ฟผ๋ฆฌ๋ฅผ ์ฒด๊ณ„์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์šฉ์ดํ–ˆ์Šต๋‹ˆ๋‹ค
    • ๊ฐ ๊ธฐ๋Šฅ๋ณ„ ๋ฉ”์†Œ๋“œ ๋ถ„๋ฆฌ๋กœ ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ์„ฑ์ด ํ–ฅ์ƒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค
  2. ์„ฑ๋Šฅ ์ตœ์ ํ™” ๊ฒฝํ—˜

    • ์ฟผ๋ฆฌ ์„ฑ๋Šฅ์„ ๊ณ ๋ คํ•œ ์„ค๊ณ„๊ฐ€ ์ค‘์š”ํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์‹ค๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค
    • ๋‹จ์ˆœ ORM ๋ฐฉ์‹๋ณด๋‹ค ๋ณต์žกํ•œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ DB ๋ ˆ๋ฒจ์—์„œ ์ฒ˜๋ฆฌํ•˜์—ฌ ์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ๊ฒฝํ—˜ํ–ˆ์Šต๋‹ˆ๋‹ค
  3. ๋น„์ฆˆ๋‹ˆ์Šค ์ธ์‚ฌ์ดํŠธ ๋„์ถœ

    • ๋ฐ์ดํ„ฐ ๊ธฐ๋ฐ˜ ํ†ต๊ณ„๋ฅผ ํ†ตํ•ด ํŒ๋งค์ž์™€ ๊ด€๋ฆฌ์ž, ์‚ฌ์šฉ์ž์—๊ฒŒ ์œ ์šฉํ•œ ์ธ์‚ฌ์ดํŠธ๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค
    • ์‚ฌ์šฉ์ž ํ–‰๋™ ํŒจํ„ด ๋ถ„์„์„ ํ†ตํ•œ ๋งž์ถคํ˜• ์„œ๋น„์Šค ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•ด์กŒ์Šต๋‹ˆ๋‹ค
  4. ํƒ€์ž… ์•ˆ์ „์„ฑ์˜ ์ค‘์š”์„ฑ

    • ์ปดํŒŒ์ผ ์‹œ์ ์— ์˜ค๋ฅ˜๋ฅผ ์žก์•„๋‚ผ ์ˆ˜ ์žˆ์–ด ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ๋ฅผ ํฌ๊ฒŒ ์ค„์ผ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค
    • ๋ณต์žกํ•œ ์ฟผ๋ฆฌ ์ž‘์„ฑ ์‹œ IDE์˜ ์ž๋™์™„์„ฑ ๊ธฐ๋Šฅ์ด ๊ฐœ๋ฐœ ์ƒ์‚ฐ์„ฑ์„ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œ์ผฐ์Šต๋‹ˆ๋‹ค

ํ”„๋กœ์ ํŠธ ํ™œ์šฉ

  1. ์ƒํ’ˆ ์ถ”์ฒœ ์‹œ์Šคํ…œ

    • ์„ฑ๋ณ„/์—ฐ๋ น๋Œ€๋ณ„ ๊ตฌ๋งค ํŒจํ„ด ๋ถ„์„
    • ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ์ธ๊ธฐ ์ƒํ’ˆ ์ถ”์ถœ
    • ์—ฐ๊ด€ ์ƒํ’ˆ ์ถ”์ฒœ
  2. ๋งค์ถœ ๋ถ„์„

    • ๊ธฐ๊ฐ„๋ณ„ ๋งค์ถœ ์ง‘๊ณ„
    • ํŒ๋งค์ž๋ณ„ ์‹ค์  ๋ถ„์„
    • ์ƒํ’ˆ๋ณ„ ํŒ๋งค ํ†ต๊ณ„
    • ์‹œ๊ฐ„๋Œ€๋ณ„ ํŒ๋งค ๋ถ„์„
    • ํŒ๋งค๋Ÿ‰ ์˜ˆ์ธก
  3. ๊ณ ๊ฐ ํ–‰๋™ ๋ถ„์„

    • ๊ตฌ๋งค ํŒจํ„ด ๋ถ„์„
    • ์žฌ๊ตฌ๋งค์œจ ๊ณ„์‚ฐ
    • ์„ฑ๋ณ„/์—ฐ๋ น๋Œ€๋ณ„ ์„ ํ˜ธ๋„ ๋ถ„์„
AWS S3

1. ์˜์กด์„ฑ ์ถ”๊ฐ€

implementation group: 'com.amazonaws', name: 'aws-java-sdk-s3', version: '1.12.780' // S3 ๋ฒ„ํ‚ท ์ ‘๊ทผ
implementation 'io.awspring.cloud:spring-cloud-aws-starter:3.1.1' // SpringBoot AWS ํ†ตํ•ฉ
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'

์‚ฌ์šฉ ๋ฒ„์ „

  • Java 17
  • Spring Boot 3.4.1

2. ์„ค์ • ํŒŒ์ผ ์ž‘์„ฑ

application.yml

spring:
  application:
    name: spring-project
  profiles:
    include: aws

application-aws.yml

cloud:
  aws:
    credentials:
      access-key: [your-access-key]
      secret-key: [your-secret-key]
    region:
      static: ap-northeast-2
    stack:
      auto: false
    s3:
      bucket: example-dev-storage-ap

3. S3 ์„ค์ • ํด๋ž˜์Šค ๊ตฌํ˜„

@Configuration
public class S3Config {
    @Value("${cloud.aws.credentials.access-key}")
    private String accessKey;

    @Value("${cloud.aws.credentials.secret-key}")
    private String secretKey;

    @Value("${cloud.aws.region.static}")
    private String region;

    @Bean
    public AmazonS3Client amazonS3Client() {
        BasicAWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey);
        
        return (AmazonS3Client) AmazonS3ClientBuilder.standard()
                .withRegion(region)
                .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
                .build();
    }
}

4. S3Service ๊ตฌํ˜„

@Service
@RequiredArgsConstructor
public class S3Service {
    private final AmazonS3Client amazonS3Client;

    @Value("${cloud.aws.s3.bucket}")
    private String bucket;
    
    // ํŒŒ์ผ ์—…๋กœ๋“œ
    public String uploadFile(String dirName, MultipartFile file) {
        try {
            validateFile(file);
            
            String fileName = createFileName(getExtension(file.getOriginalFilename()));
            String fileUrl = dirName + "/" + fileName;

            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentType(file.getContentType());
            metadata.setContentLength(file.getSize());

            amazonS3Client.putObject(
                    new PutObjectRequest(bucket, fileUrl, file.getInputStream(), metadata)
                            .withCannedAcl(CannedAccessControlList.PublicRead)
            );

            return amazonS3Client.getUrl(bucket, fileUrl).toString();

        } catch (IOException e) {
            throw new BobIssueException(ResponseCode.FILE_UPLOAD_ERROR);
        }
    }
    
    // ํŒŒ์ผ ๊ฒ€์ฆ
    private void validateFile(MultipartFile file) {
        String contentType = file.getContentType();
        if (contentType == null || !contentType.startsWith("image/")) {
            throw new BobIssueException(ResponseCode.INVALID_FILE_TYPE);
        }

        if (file.getSize() > 10 * 1024 * 1024) {
            throw new BobIssueException(ResponseCode.FILE_SIZE_EXCEED);
        }
    }
    
    // ํŒŒ์ผ๋ช… ์ƒ์„ฑ
    private String createFileName(String ext) {
        return new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())
                + "-"
                + UUID.randomUUID().toString()
                + ext;
    }

    private String getExtension(String fileName) {
        if (fileName == null) return "";
        int lastIndex = fileName.lastIndexOf(".");
        if (lastIndex == -1) return "";
        return fileName.substring(lastIndex);
    }
    
    // ์—ฌ๋Ÿฌ ํŒŒ์ผ ์—…๋กœ๋“œ
    public List<String> uploadFiles(String dirName, List<MultipartFile> files) {
        return files.stream()
                .map(file -> uploadFile(dirName, file))
                .collect(Collectors.toList());
    }
    
    // ํŒŒ์ผ ์‚ญ์ œ
    public void deleteFile(String fileUrl) {
        try {
            String key = extractKeyFromUrl(fileUrl);
            amazonS3Client.deleteObject(bucket, key);
        } catch (Exception e) {
            throw new BobIssueException(ResponseCode.FAILED_DELETE_IMAGE);
        }
    }

    private String extractKeyFromUrl(String fileUrl) {
        try {
            java.net.URL url = new java.net.URL(fileUrl);
            String path = url.getPath();
            if (path.startsWith("/")) {
                path = path.substring(1);
            }
            return path;
        } catch (Exception e) {
            throw new BobIssueException(ResponseCode.INVALID_FILE_URL);
        }
    }

    public void deleteFiles(List<String> fileUrls) {
        for (String fileUrl : fileUrls) {
            deleteFile(fileUrl);
        }
    }
}

5. ์‚ฌ์šฉ ์˜ˆ์‹œ

// ๋‹จ์ผ ํŒŒ์ผ ์—…๋กœ๋“œ
String fileUrl = s3Service.uploadFile("images", multipartFile);

// ์—ฌ๋Ÿฌ ํŒŒ์ผ ์—…๋กœ๋“œ
List<String> fileUrls = s3Service.uploadFiles("images", multipartFiles);

// ํŒŒ์ผ ์‚ญ์ œ
s3Service.deleteFile(fileUrl);

AWS S3 ๊ตฌํ˜„์„ ํ†ตํ•ด ์–ป์€ ์ธ์‚ฌ์ดํŠธ

  1. ํด๋ผ์šฐ๋“œ ์Šคํ† ๋ฆฌ์ง€์˜ ์ด์ 

    • ์„œ๋ฒ„ ๋ถ€ํ•˜ ๊ฐ์†Œ ๋ฐ ์ด๋ฏธ์ง€ ๋กœ๋”ฉ ์†๋„ ๊ฐœ์„ 
    • ๋Œ€์šฉ๋Ÿ‰ ํŒŒ์ผ์˜ ์•ˆ์ •์  ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ
    • ์ƒํ’ˆ ์ด๋ฏธ์ง€ ๋‹ค์ˆ˜ ๊ด€๋ฆฌ์— ํ•„์š”ํ•œ ํ™•์žฅ์„ฑ ํ™•๋ณด
  2. ๋ณด์•ˆ๊ณผ ์„ฑ๋Šฅ์˜ ๊ท ํ˜•

    • ์‚ฌ์šฉ์ž ์ž…๋ ฅ๊ฐ’ ๊ฒ€์ฆ์˜ ์ค‘์š”์„ฑ ์ธ์‹
    • XSS, ์•…์„ฑ์ฝ”๋“œ ๋“ฑ ๋ณด์•ˆ ์ทจ์•ฝ์  ์‚ฌ์ „ ๋ฐฉ์ง€
  3. ๊ฐœ๋ฐœ ์ƒ์‚ฐ์„ฑ ํ–ฅ์ƒ

    • ํŒŒ์ผ ๊ด€๋ฆฌ ๋กœ์ง ์ถ”์ƒํ™”๋กœ ์ฝ”๋“œ ๊ฐ„๊ฒฐํ™”
    • ์—ฌ๋Ÿฌ ๊ธฐ๋Šฅ์—์„œ ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅ
    • ํ†ต์ผ๋œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋กœ ์œ ์ง€๋ณด์ˆ˜ ์šฉ์ด
  4. ๋น„์šฉ ์ตœ์ ํ™”

    • S3 ์‚ฌ์šฉ ๋น„์šฉ ๋ชจ๋‹ˆํ„ฐ๋ง ๋ฐฉ๋ฒ• ํ•™์Šต
    • ๋ถˆํ•„์š”ํ•œ ํŒŒ์ผ ์ €์žฅ ๋ฐฉ์ง€ ์ •์ฑ… ์ˆ˜๋ฆฝ
OAuth2

OAuth2

๊ฐœ๋…

  • OAuth 2.0์€ ์ธ์ฆ ๋ฐ ๊ถŒํ•œ ๋ถ€์—ฌ๋ฅผ ์œ„ํ•œ ์—…๊ณ„ ํ‘œ์ค€ ํ”„๋กœํ† ์ฝœ
  • ์‚ฌ์šฉ์ž์˜ ๊ณ„์ • ์ •๋ณด๋ฅผ ์™ธ๋ถ€ ์„œ๋น„์Šค์— ์ œ๊ณตํ•˜์ง€ ์•Š๊ณ  ์•ˆ์ „ํ•˜๊ฒŒ ๋กœ๊ทธ์ธ ๋ฐ ๊ถŒํ•œ์„ ์œ„์ž„ํ•˜๋Š” ๋ฐฉ์‹

Spring Security + OAuth2 ๋กœ๊ทธ์ธ ํ๋ฆ„

  1. ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ ํด๋ฆญ
  2. Spring Security์˜ OAuth2 Client๊ฐ€ ์นด์นด์˜ค ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋””๋ ‰์…˜
  3. ์‚ฌ์šฉ์ž๊ฐ€ ์นด์นด์˜ค ๋กœ๊ทธ์ธ ํ›„ ์ธ๊ฐ€ ์ฝ”๋“œ ๋ฐ˜ํ™˜
  4. Spring Security๊ฐ€ ์ธ๊ฐ€ ์ฝ”๋“œ๋ฅผ ์ด์šฉํ•ด Access Token ์š”์ฒญ
  5. Access Token์„ ์ด์šฉํ•ด ์‚ฌ์šฉ์ž ์ •๋ณด ์š”์ฒญ
  6. ์‘๋‹ต๋ฐ›์€ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํšŒ์›๊ฐ€์ž… ๋˜๋Š” ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ
  7. JWT๋ฅผ ๋ฐœ๊ธ‰ํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ์— ์ „๋‹ฌ
JWT ๊ธฐ๋ฐ˜ Access Token & Refresh Token

JWT

๊ฐœ๋…

  • JWT(JSON Web Token)๋Š” ์‚ฌ์šฉ์ž ์ธ์ฆ ๋ฐ ์ •๋ณด ์ „๋‹ฌ์„ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ํ† ํฐ ๋ฐฉ์‹
  • JSON ํ˜•ํƒœ๋กœ ์ •๋ณด๋ฅผ ๋‹ด์•„ Base64Url๋กœ ์ธ์ฝ”๋”ฉํ•˜์—ฌ ์‚ฌ์šฉ
  • ์„œ๋ช…์„ ํฌํ•จํ•˜์—ฌ ๋ณ€์กฐ๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Œ
  • ๋ณ„๋„์˜ ์„ธ์…˜ ์ €์žฅ์†Œ ์—†์ด ์ธ์ฆ ๊ฐ€๋Šฅํ•ด Statelessํ•จ

๊ตฌ์กฐ

  • Header : ์•Œ๊ณ ๋ฆฌ์ฆ˜, ํƒ€์ž… ์ •๋ณด
  • Payload : ์‚ฌ์šฉ์ž ์ •๋ณด, ๊ถŒํ•œ ๋“ฑ
  • Signature : ์„œ๋ช…, ๋ณ€์กฐ ๋ฐฉ์ง€

์‚ฌ์šฉ ์ด์œ 

  • ์„ธ์…˜ ๋ฐฉ์‹๋ณด๋‹ค ํšจ์œจ์ 

    • ์„œ๋ฒ„์—์„œ ๋ณ„๋„์˜ ์„ธ์…˜ ์ €์žฅ ์—†์ด Stateless ์ธ์ฆ ๊ฐ€๋Šฅ

    • ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์„œ๋ฒ„์—์„œ๋„ ๋™์ผํ•œ ์ธ์ฆ ์œ ์ง€ ๊ฐ€๋Šฅ

  • ๋ณด์•ˆ์„ฑ์ด ๋†’์Œ

  • RESTful API์— ์ ํ•ฉ

Access Token & Refresh Token ์ „๋žต ๊ตฌํ˜„ ๋ฐฉ์‹

1. JWT ๊ธฐ๋ฐ˜์˜ Token ๋ฐœ๊ธ‰

  • Access Token

    • ์งง์€ ์œ ํšจ๊ธฐ๊ฐ„

    • ์‚ฌ์šฉ์ž ์ธ์ฆ ์‹œ API ์š”์ฒญ์— ์‚ฌ์šฉ

    • ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์š”์ฒญ๋งˆ๋‹ค ํฌํ•จํ•˜์—ฌ ์„œ๋ฒ„๋กœ ์ „์†ก

  • Refresh Token

    • ๊ธด ์œ ํšจ๊ธฐ๊ฐ„

    • Access Token์ด ๋งŒ๋ฃŒ๋˜์—ˆ์„ ๋•Œ ์ƒˆ๋กœ ๋ฐœ๊ธ‰ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ

    • Redis์— ์ €์žฅํ•˜์—ฌ ๋ณด์•ˆ ๊ฐ•ํ™”

2. Access Token ๊ฒ€์ฆ

  • API ์š”์ฒญ๋งˆ๋‹ค Authorization: Bearer {AccessToken} ํ—ค๋”๋ฅผ ํ™•์ธ

  • Access Token์ด ์œ ํšจํ•˜๋ฉด โ†’ ์š”์ฒญ ์ฒ˜๋ฆฌ ํ›„ ์‘๋‹ต ๋ฐ˜ํ™˜

  • Access Token์ด ๋งŒ๋ฃŒ๋˜์—ˆ์œผ๋ฉด Refresh Token์„ ํ™•์ธ

3. Refresh Token ๊ฒ€์ฆ ๋ฐ Access Token ์žฌ๋ฐœ๊ธ‰

  • Refresh Token์€ Redis์— ์ €์žฅ

  • Access Token์ด ๋งŒ๋ฃŒ๋˜์—ˆ์„ ๋•Œ, Refresh Token์„ ํ™•์ธ

    • ์œ ํšจํ•˜๋ฉด โ†’ ์ƒˆ๋กœ์šด Access Token์„ ๋ฐœ๊ธ‰ ํ›„ ์‘๋‹ต

    • ์œ ํšจํ•˜์ง€ ์•Š์œผ๋ฉด โ†’ ๋กœ๊ทธ์•„์›ƒ ์ฒ˜๋ฆฌ

4. ๋กœ๊ทธ์•„์›ƒ ์‹œ Refresh Token ์‚ญ์ œ

  • ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์•„์›ƒํ•˜๋ฉด Redis์—์„œ ํ•ด๋‹น Refresh Token์„ ์ฆ‰์‹œ ์‚ญ์ œ

  • ์ดํ›„ ํ•ด๋‹น ์‚ฌ์šฉ์ž๋Š” Refresh Token์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ โ†’ ์žฌ๋กœ๊ทธ์ธ์ด ํ•„์š”

๋ณด์•ˆ์  ๊ฐ•์ 

1. Refresh Token ํƒˆ์ทจ ๋ฐฉ์ง€

ํด๋ผ์ด์–ธํŠธ์— ์ €์žฅํ•˜์ง€ ์•Š๊ณ  ์„œ๋ฒ„(Redis)์—์„œ๋งŒ ๊ด€๋ฆฌํ•˜์—ฌ ์œ ์ถœ ์œ„ํ—˜ ๊ฐ์†Œ

2. ํ† ํฐ ๊ฐ•์ œ ๋งŒ๋ฃŒ ๊ฐ€๋Šฅ

  • WT ์ž์ฒด๋Š” ๋งŒ๋ฃŒ ์ „๊นŒ์ง€ ๋ฌดํšจํ™”ํ•  ์ˆ˜ ์—†์ง€๋งŒ, Redis์—์„œ Refresh Token์„ ๊ด€๋ฆฌํ•˜๋ฉด ์›ํ•˜๋Š” ์‹œ์ ์— ์ฆ‰์‹œ ๋งŒ๋ฃŒ ๊ฐ€๋Šฅ

  • ๋กœ๊ทธ์•„์›ƒ ์‹œ Refresh Token์„ ์‚ญ์ œํ•˜์—ฌ ํƒˆ์ทจ๋œ ํ† ํฐ์ด๋”๋ผ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ

3. ์„œ๋ฒ„ ํ™•์žฅ์„ฑ ์œ ์ง€

Statelessํ•œ JWT์˜ ์žฅ์ ์„ ์œ ์ง€ํ•˜๋ฉด์„œ๋„ Redis๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์•ˆ์ „ํ•˜๊ฒŒ ์ธ์ฆ ๊ด€๋ฆฌ ๊ฐ€๋Šฅ

WebSocket

WebSocket

WebSocket์ด๋ž€?

WebSocket์€ ์‹ค์‹œ๊ฐ„ ์–‘๋ฐฉํ–ฅ ํ†ต์‹ ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” ํ”„๋กœํ† ์ฝœ์ž…๋‹ˆ๋‹ค.

  • ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„๊ฐ€ ์ง€์†์ ์œผ๋กœ ์—ฐ๊ฒฐ์„ ์œ ์ง€ํ•˜๋ฉฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›์Œ
  • HTTP๋ณด๋‹ค ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋‚ฎ๊ณ  ๋น ๋ฆ„
  • ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ…, ์•Œ๋ฆผ ์‹œ์Šคํ…œ ๋“ฑ ๋‹ค์–‘ํ•œ ์„œ๋น„์Šค์— ํ™œ์šฉ ๊ฐ€๋Šฅ

WebSocket๊ณผ HTTP์˜ ์ฐจ์ด์ 

๋น„๊ต ํ•ญ๋ชฉ WebSocket HTTP
์—ฐ๊ฒฐ ๋ฐฉ์‹ ์ง€์†์ ์ธ ์—ฐ๊ฒฐ ์œ ์ง€ ์š”์ฒญ-์‘๋‹ต ํ›„ ์—ฐ๊ฒฐ ์ข…๋ฃŒ
๋ฐ์ดํ„ฐ ๊ตํ™˜ ๋ฐฉ์‹ ํด๋ผ์ด์–ธํŠธ โ†” ์„œ๋ฒ„ ๊ฐ„ ์ž์œ ๋กญ๊ฒŒ ๋ฉ”์‹œ์ง€ ์ „์†ก ๊ฐ€๋Šฅ ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ์— ์„œ๋ฒ„๊ฐ€ ์‘๋‹ต
์‚ฌ์šฉ ์‚ฌ๋ก€ ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ…, ์ฃผ์‹ ์‹œ์„ธ, ์•Œ๋ฆผ ์ผ๋ฐ˜์ ์ธ ์›นํŽ˜์ด์ง€ ์š”์ฒญ/์‘๋‹ต

STOMP vs Socket.IO

๋น„๊ต ํ•ญ๋ชฉ STOMP Socket.IO
๊ธฐ๋ฐ˜ ํ”„๋กœํ† ์ฝœ WebSocket + ๋ฉ”์‹œ์ง• ํ”„๋กœํ† ์ฝœ WebSocket + HTTP ํด๋ฐฑ
์„œ๋ฒ„ ํ™˜๊ฒฝ Spring WebSocket๊ณผ ๊ฒฐํ•ฉ Node.js ๊ธฐ๋ฐ˜์˜ ์‹ค์‹œ๊ฐ„ ์•ฑ
๋ฐ์ดํ„ฐ ์ „์†ก ๋ฉ”์‹œ์ง€ ํ ๊ธฐ๋ฐ˜ (Pub/Sub) ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ํ†ต์‹ 
๋ธŒ๋ผ์šฐ์ € ์ง€์› WebSocket ์ง€์› ํ•„์š” WebSocket ๋ฏธ์ง€์› ์‹œ HTTP ํด๋ง ์‚ฌ์šฉ ๊ฐ€๋Šฅ
์‚ฌ์šฉ ์‚ฌ๋ก€ ๊ธฐ์—…ํ˜• ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜, ์ฑ„ํŒ… ์‹œ์Šคํ…œ, ๋ฉ”์‹œ์ง€ ํ ์‹ค์‹œ๊ฐ„ ๊ฒŒ์ž„, ์†Œ์…œ ํ”ผ๋“œ, ์•Œ๋ฆผ ์‹œ์Šคํ…œ

STOMP๋ฅผ ์‚ฌ์šฉํ•œ ์ด์œ 

  1. Spring WebSocket๊ณผ์˜ ๋†’์€ ํ˜ธํ™˜์„ฑ
- Spring Messaging์„ ํ†ตํ•ด ์‰ฝ๊ฒŒ ๊ตฌํ˜„ ๊ฐ€๋Šฅ

- Spring Security์™€๋„ ์—ฐ๋™์ด ์‰ฌ์›€
  1. ๋ฉ”์‹œ์ง€ ๋ธŒ๋กœ์ปค(Pub/Sub) ์ง€์›
- STOMP๋Š” RabbitMQ, ActiveMQ, Redis Pub/Sub ๊ฐ™์€ ๋ฉ”์‹œ์ง€ ๋ธŒ๋กœ์ปค์™€ ํ†ตํ•ฉ ๊ฐ€๋Šฅ

- ์—ฌ๋Ÿฌ ์„œ๋ฒ„์—์„œ ๊ฐ™์€ ๋ฉ”์‹œ์ง€๋ฅผ ๊ตฌ๋…ํ•˜๊ณ  ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด ํ™•์žฅ์„ฑ์ด ๋›ฐ์–ด๋‚จ
  1. ์ฑ„ํŒ…๋ฐฉ ๊ตฌ์กฐ์— ์ ํ•ฉํ•œ ๋ฉ”์‹œ์ง• ์‹œ์Šคํ…œ
- ์ฑ„ํŒ…๋ฐฉ๋งˆ๋‹ค ๊ฐœ๋ณ„ topic์„ ๋งŒ๋“ค์–ด ๊ตฌ๋…ํ•˜๋ฉด, ํ•ด๋‹น ๋ฐฉ์˜ ์‚ฌ์šฉ์ž๋“ค๋งŒ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ์Œ

- ๋ฉ”์‹œ์ง€๋ฅผ ๋‹ค์ˆ˜์˜ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ „์†ก ์ฒ˜๋ฆฌ์— ์šฉ์ด
  1. ์œ ์ง€๋ณด์ˆ˜ ์šฉ์ด
- STOMP๋Š” WebSocket์„ ์ง์ ‘ ๋‹ค๋ฃจ๋Š” ๊ฒƒ๋ณด๋‹ค ์ถ”์ƒํ™”๋˜์–ด ์žˆ์–ด ์œ ์ง€๋ณด์ˆ˜ํ•˜๊ธฐ ์‰ฌ์›€

- ํ…์ŠคํŠธ ๊ธฐ๋ฐ˜ ํ”„๋กœํ† ์ฝœ์ด๋ฏ€๋กœ ๋ฉ”์‹œ์ง€ ๋””๋ฒ„๊น…์ด ์‰ฌ์›€

WebSocket์„ ์ด์šฉํ•œ ์ฑ„ํŒ… ๊ตฌํ˜„ ๋ฐฉ์‹

1. ํด๋ผ์ด์–ธํŠธ๊ฐ€ WebSocket ์—ฐ๊ฒฐ ์š”์ฒญ

2. ์„œ๋ฒ„๊ฐ€ STOMP ์„ธ์…˜์„ ์ƒ์„ฑํ•˜๊ณ  ์—ฐ๊ฒฐ ์œ ์ง€

3. ์‚ฌ์šฉ์ž๊ฐ€ ํŠน์ • ์ฑ„ํŒ…๋ฐฉ์„ ๊ตฌ๋…

4. ๋ฉ”์‹œ์ง€ ๋ฐœ์†ก

5. ์„œ๋ฒ„๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ํ•ด๋‹น ์ฑ„ํŒ…๋ฐฉ์˜ ๋ชจ๋“  ์‚ฌ์šฉ์ž์—๊ฒŒ ์ „๋‹ฌ

6. ์‚ฌ์šฉ์ž๊ฐ€ ํ‡ด์žฅํ•˜๋ฉด ์„ธ์…˜ ์ข…๋ฃŒ

Redis์™€ MongoDB๋ฅผ ํ™œ์šฉํ•œ ์ฑ„ํŒ… ๊ด€๋ฆฌ

Redis

Redis์˜ ํŠน์ง•

  • ์ธ๋ฉ”๋ชจ๋ฆฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค -> ๋ฐ์ดํ„ฐ๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•˜์—ฌ ๋งค์šฐ ๋น ๋ฅธ ์†๋„๋กœ ์ฝ๊ณ  ์“ธ ์ˆ˜ ์žˆ์Œ
  • Key-Value ๊ตฌ์กฐ โ†’ ๋‹จ์ˆœํ•œ ๊ตฌ์กฐ๋กœ ๋ฐ์ดํ„ฐ ์ €์žฅ ๋ฐ ์ ‘๊ทผ์ด ์šฉ์ด
  • Pub/Sub ๊ธฐ๋Šฅ ์ œ๊ณต โ†’ ๋ฉ”์‹œ์ง€ ๋ธŒ๋กœ์ปค ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•˜๋ฉฐ ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ…์— ์ ํ•ฉ
  • TTL(๋งŒ๋ฃŒ ์‹œ๊ฐ„) ์„ค์ • ๊ฐ€๋Šฅ โ†’ ํŠน์ • ์‹œ๊ฐ„ ์ดํ›„ ์ž๋™ ์‚ญ์ œ๋˜๋Š” ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ ๊ฐ€๋Šฅ
  • ๋‹จ์  : ์˜๊ตฌ ์ €์žฅ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋ฉฐ ๋ฐ์ดํ„ฐ๊ฐ€ ๋งŽ์•„์งˆ์ˆ˜๋ก ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ์ฆ๊ฐ€

MongoDB

MongoDB์˜ ํŠน์ง•

  • NoSQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค โ†’ JSON ํ˜•ํƒœ์˜ ๋น„์ •ํ˜• ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐ ์ตœ์ ํ™”
  • ์ˆ˜์ง ๋ฐ ์ˆ˜ํ‰ ํ™•์žฅ ์šฉ์ด โ†’ ์ƒค๋”ฉ(Sharding)๊ณผ ๋ณต์ œ(Replication) ๊ธฐ๋Šฅ์œผ๋กœ ๋Œ€๊ทœ๋ชจ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ
  • ๋น ๋ฅธ ์กฐํšŒ ์„ฑ๋Šฅ โ†’ ์ธ๋ฑ์Šค๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž๋ณ„/์ฑ„ํŒ…๋ฐฉ๋ณ„ ๋ฐ์ดํ„ฐ ๊ฒ€์ƒ‰ ์ตœ์ ํ™” ๊ฐ€๋Šฅ
  • ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์˜๊ตฌ์ ์œผ๋กœ ์ €์žฅ ๊ฐ€๋Šฅ โ†’ ์ฑ„ํŒ… ๋กœ๊ทธ, ์ฒจ๋ถ€ ํŒŒ์ผ, ์œ ์ € ํ™œ๋™ ๊ธฐ๋ก ๊ด€๋ฆฌ์— ์ ํ•ฉ
  • ๋‹จ์  : ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์ฒ˜๋Ÿผ ๊ฐ•๋ ฅํ•œ ํŠธ๋žœ์žญ์…˜ ์ง€์› ๋ถ€์กฑ (ํ•˜์ง€๋งŒ ์ฑ„ํŒ… ๋ฐ์ดํ„ฐ์—๋Š” ํฐ ๋ฌธ์ œ ์—†์Œ)

MySQL

MySQL์˜ ํŠน์ง•

  • ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค(RDBMS) โ†’ ํ…Œ์ด๋ธ” ๊ฐ„ ๊ด€๊ณ„๋ฅผ ์„ค์ •ํ•˜์—ฌ ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ ์œ ์ง€
  • ACID(Atomicity, Consistency, Isolation, Durability) ๋ณด์žฅ โ†’ ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ์— ๊ฐ•์ 
  • ์ •ํ˜•ํ™”๋œ ๋ฐ์ดํ„ฐ ์ €์žฅ์— ์ ํ•ฉ โ†’ ์ •ํ•ด์ง„ ์Šคํ‚ค๋งˆ์— ๋งž์ถฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด ๊ฐ•์ 

MySQL๋กœ ์ฑ„ํŒ… ๊ด€๋ฆฌ๋ฅผ ํ•˜์ง€ ์•Š์€ ์ด์œ 

1. ํŠธ๋žœ์žญ์…˜ ๋ถ€๋‹ด

์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ…์—์„œ MySQL์€ ๋นˆ๋ฒˆํ•œ ๋ฐ์ดํ„ฐ ์‚ฝ์ž…ยท์‚ญ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ์„ฑ๋Šฅ ์ €ํ•˜ ๊ฐ€๋Šฅ

2. ํ™•์žฅ์„ฑ ๋ถ€์กฑ

์Šค์ผ€์ผ ์•„์›ƒ(Scale-out)์ด ์–ด๋ ต๊ณ , ํŠธ๋ž˜ํ”ฝ ์ฆ๊ฐ€ ์‹œ ์ฒ˜๋ฆฌ ์„ฑ๋Šฅ์ด ๊ธ‰๊ฒฉํžˆ ์ €ํ•˜๋จ

3. ๋น„์ •ํ˜• ๋ฐ์ดํ„ฐ ์ €์žฅ ๋น„ํšจ์œจ

JSON ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๋ณ„๋„์˜ ํŒŒ์‹ฑ ๊ณผ์ •์ด ํ•„์š”ํ•˜์—ฌ ์„ฑ๋Šฅ ์ €ํ•˜ ๋ฐœ์ƒ

Redis์™€ MongoDB๋ฅผ ์ด์šฉํ•˜์—ฌ ์ฑ„ํŒ…์„ ๊ด€๋ฆฌํ•˜๊ฒŒ ๋œ ์ด์œ ์™€ ์žฅ์ 

Redis๋ฅผ ํ™œ์šฉํ•˜๋Š” ์ด์œ  (์‹ค์‹œ๊ฐ„ ๋ฉ”์‹œ์ง€ ์ฒ˜๋ฆฌ)

  • ๋น ๋ฅธ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์†๋„

    • ์ธ๋ฉ”๋ชจ๋ฆฌ ๊ธฐ๋ฐ˜์ด๋ฏ€๋กœ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ์ฃผ๊ณ ๋ฐ›์„ ์ˆ˜ ์žˆ์Œ
  • Pub/Sub ๊ธฐ๋Šฅ ์ง€์›

    • ๋‹ค์ˆ˜์˜ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋™์‹œ์— ๋ฉ”์‹œ์ง€๋ฅผ ๋ธŒ๋กœ๋“œ์บ์ŠคํŠธ ๊ฐ€๋Šฅ
  • ์‚ฌ์šฉ์ž ์˜จ๋ผ์ธ ์ƒํƒœ ๊ด€๋ฆฌ ๊ฐ€๋Šฅ

    • TTL์„ ํ™œ์šฉํ•˜์—ฌ ์ผ์ • ์‹œ๊ฐ„ ํ›„ ์ž๋™์œผ๋กœ ๋ฐ์ดํ„ฐ ์‚ญ์ œ ๊ฐ€๋Šฅ

MongoDB๋ฅผ ํ™œ์šฉํ•˜๋Š” ์ด์œ  (์ฑ„ํŒ… ์ €์žฅ)

  • ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ ์ €์žฅ ๊ฐ€๋Šฅ

    • JSON ํ˜•์‹์œผ๋กœ ๋น„์ •ํ˜• ๋ฐ์ดํ„ฐ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌ
  • ๊ฒ€์ƒ‰ ๋ฐ ์กฐํšŒ ์ตœ์ ํ™”

    • ์ธ๋ฑ์Šค๋ฅผ ํ™œ์šฉํ•˜์—ฌ ํŠน์ • ์‚ฌ์šฉ์ž ๋˜๋Š” ์ฑ„ํŒ…๋ฐฉ์˜ ๋ฉ”์‹œ์ง€๋ฅผ ๋น ๋ฅด๊ฒŒ ๊ฒ€์ƒ‰ ๊ฐ€๋Šฅ
  • ํ™•์žฅ์„ฑ ์šฐ์ˆ˜

    • ํŠธ๋ž˜ํ”ฝ ์ฆ๊ฐ€ ์‹œ ์ƒค๋”ฉ์„ ํ†ตํ•ด ์—ฌ๋Ÿฌ ๋…ธ๋“œ์— ๋ฐ์ดํ„ฐ ๋ถ„์‚ฐ ๊ฐ€๋Šฅ

์˜๊ตฌ ์ €์žฅ์„ ์œ„ํ•ด Redis์™€ MongoDB๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ  ๋ฐ ์žฅ์ 

  • ํ•˜์ด๋ธŒ๋ฆฌ๋“œ ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ (ํœ˜๋ฐœ์„ฑ + ์˜๊ตฌ ์ €์žฅ)

    • Redis๋Š” ๋ฉ”๋ชจ๋ฆฌ ๊ธฐ๋ฐ˜์ด๋ฏ€๋กœ ๋น ๋ฅด์ง€๋งŒ ๋ฐ์ดํ„ฐ๊ฐ€ ํœ˜๋ฐœ์„ฑ(Volatile)์ด๋ผ ์˜๊ตฌ ์ €์žฅ ๋ถˆ๊ฐ€๋Šฅ

    • MongoDB๋Š” ๋””์Šคํฌ ๊ธฐ๋ฐ˜์ด๋ฏ€๋กœ ์˜๊ตฌ ์ €์žฅ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ์‹ค์‹œ๊ฐ„ ์ฒ˜๋ฆฌ๊ฐ€ ์–ด๋ ค์›€

    • ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ…์€ Redis์—์„œ ๊ด€๋ฆฌํ•˜๊ณ , ์ผ์ • ์ฃผ๊ธฐ๋งˆ๋‹ค ๋ฐ์ดํ„ฐ๋ฅผ MongoDB๋กœ ์ €์žฅํ•˜์—ฌ ์˜๊ตฌ ๋ณด๊ด€

  • ๋น ๋ฅธ ์‘๋‹ต๊ณผ ๋ฐ์ดํ„ฐ ๋ณด์กด์„ ๋™์‹œ์— ํ•ด๊ฒฐ

    • ์‚ฌ์šฉ์ž๊ฐ€ ์ฑ„ํŒ…๋ฐฉ์— ์ ‘์†ํ•˜๋ฉด Redis์—์„œ ์ตœ๊ทผ ์ฑ„ํŒ… ๋ฉ”์‹œ์ง€๋ฅผ ๋น ๋ฅด๊ฒŒ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ

    • ๊ณผ๊ฑฐ ๋ฉ”์‹œ์ง€ ์กฐํšŒ ์‹œ MongoDB์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฒ€์ƒ‰ํ•˜์—ฌ ์ œ๊ณต

  • ์‹œ์Šคํ…œ ์•ˆ์ •์„ฑ ๋ฐ ์žฅ์•  ๋Œ€์‘

    • Redis๋Š” ๋ฉ”๋ชจ๋ฆฌ ๊ธฐ๋ฐ˜์ด๋ฏ€๋กœ ์„œ๋ฒ„ ์žฌ์‹œ์ž‘ ์‹œ ๋ฐ์ดํ„ฐ๊ฐ€ ์†์‹ค๋  ์ˆ˜ ์žˆ์Œ

    • MongoDB์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋Š” ์„œ๋ฒ„ ์žฅ์•  ๋ฐœ์ƒ ์‹œ์—๋„ ์œ ์ง€๋˜์–ด ์ฑ„ํŒ… ๊ธฐ๋ก์„ ๋ณต์› ๊ฐ€๋Šฅ

WebRtc

WebRTC

WebRTC๋ž€?

WebRTC(Web Real-Time Communication)๋Š” ์›น ๋ธŒ๋ผ์šฐ์ € ๋ฐ ๋ชจ๋ฐ”์ผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ํ”Œ๋Ÿฌ๊ทธ์ธ ์—†์ด ์‹ค์‹œ๊ฐ„ ์Œ์„ฑยท์˜์ƒ ํ†ต์‹ ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” ๊ธฐ์ˆ 

  • P2P (Peer-to-Peer) ์—ฐ๊ฒฐ์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ง์ ‘ ์ฃผ๊ณ ๋ฐ›์„ ์ˆ˜ ์žˆ์Œ
  • ๋‚ฎ์€ ์ง€์—ฐ์‹œ๊ฐ„(Low Latency)์„ ์ œ๊ณตํ•˜์—ฌ ์‹ค์‹œ๊ฐ„ ์†Œํ†ต์ด ๊ฐ€๋Šฅ
  • ์›น ํ‘œ์ค€ API๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ณ„๋„์˜ ํ”Œ๋Ÿฌ๊ทธ์ธ ์—†์ด ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

WebRTC์˜ ์ฃผ์š” ๊ธฐ๋Šฅ

  • ์˜ค๋””์˜ค ๋ฐ ๋น„๋””์˜ค ์ŠคํŠธ๋ฆฌ๋ฐ
    • ์›น ๋ธŒ๋ผ์šฐ์ € ๊ฐ„ ์‹ค์‹œ๊ฐ„ ์˜์ƒ ๋ฐ ์Œ์„ฑ ์ „์†ก
  • P2P ๊ธฐ๋ฐ˜ ํ†ต์‹ 
    • ์ค‘์•™ ์„œ๋ฒ„๋ฅผ ๊ฑฐ์น˜์ง€ ์•Š๊ณ , ์‚ฌ์šฉ์ž ๊ฐ„ ์ง์ ‘ ์—ฐ๊ฒฐ(Peer-to-Peer) ๊ฐ€๋Šฅ
  • ๋‹ค์–‘ํ•œ ๋„คํŠธ์›Œํฌ ํ™˜๊ฒฝ ์ง€์›
    • NAT ๋ฐ ๋ฐฉํ™”๋ฒฝ์„ ์šฐํšŒํ•˜์—ฌ ์—ฐ๊ฒฐ ๊ฐ€๋Šฅ (STUN/TURN ์„œ๋ฒ„ ํ™œ์šฉ)

WebRTC ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

WebRTC์˜ ํ•ต์‹ฌ 3์š”์†Œ

  • getUserMedia()
    • ์‚ฌ์šฉ์ž์˜ ์นด๋ฉ”๋ผ์™€ ๋งˆ์ดํฌ ๊ถŒํ•œ์„ ์š”์ฒญํ•˜์—ฌ ์˜์ƒยท์˜ค๋””์˜ค ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ด
  • RTCPeerConnection
    • P2P ์—ฐ๊ฒฐ์„ ์„ค์ •ํ•˜๊ณ , ๋ฏธ๋””์–ด ๋ฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†ก

WebRTC ๋™์ž‘ ๋ฐฉ์‹

  1. ์‚ฌ์šฉ์ž๊ฐ€ ์นด๋ฉ”๋ผยท๋งˆ์ดํฌ ์ ‘๊ทผ์„ ํ—ˆ์šฉํ•˜๋ฉด getUserMedia()๋กœ ๋ฏธ๋””์–ด ์ŠคํŠธ๋ฆผ์„ ๊ฐ€์ ธ์˜ด
  2. RTCPeerConnection์„ ์ƒ์„ฑํ•˜์—ฌ P2P ์—ฐ๊ฒฐ์„ ์„ค์ •
  3. SDP(Session Description Protocol) ๊ตํ™˜์„ ํ†ตํ•ด ์„œ๋กœ์˜ ์—ฐ๊ฒฐ ์ •๋ณด๋ฅผ ๊ณต์œ 
  4. ICE(Interactive Connectivity Establishment) ํ›„๋ณด๋ฅผ ๊ตํ™˜ํ•˜์—ฌ ์ตœ์ ์˜ ๋„คํŠธ์›Œํฌ ๊ฒฝ๋กœ ์„ค์ •
  5. P2P ์—ฐ๊ฒฐ์ด ์™„๋ฃŒ๋˜๋ฉด, ์˜ค๋””์˜คยท๋น„๋””์˜ค ๋ฐ์ดํ„ฐ๊ฐ€ ์ŠคํŠธ๋ฆฌ๋ฐ๋จ

WebRTC๋ฅผ ์‚ฌ์šฉํ•œ ์ด์œ  (๋ผ์ด๋ธŒ ์ปค๋จธ์Šค์—์„œ WebRTC์˜ ์žฅ์ )

๋‚ฎ์€ ์ง€์—ฐ์‹œ๊ฐ„ (Low Latency)์œผ๋กœ ์‹ค์‹œ๊ฐ„ ์†Œํ†ต ๊ฐ€๋Šฅ

  • ๊ธฐ์กด HTTP ๊ธฐ๋ฐ˜ ์ŠคํŠธ๋ฆฌ๋ฐ๋ณด๋‹ค WebRTC๋Š” ๊ฑฐ์˜ ์‹ค์‹œ๊ฐ„(์ดˆ์ €์ง€์—ฐ) ์ „์†ก์„ ์ œ๊ณต
  • ํŒ๋งค์ž์™€ ๊ณ ๊ฐ ๊ฐ„ ๋น ๋ฅธ ํ”ผ๋“œ๋ฐฑ์„ ์ฃผ๊ณ ๋ฐ›์•„ ์‹ค์‹œ๊ฐ„ ์†Œํ†ต ๊ฐ€๋Šฅ

๋ณ„๋„์˜ ํ”Œ๋Ÿฌ๊ทธ์ธ ์—†์ด ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

  • ํฌ๋กœ์Šค ํ”Œ๋žซํผ ์ง€์› โ†’ PC/๋ชจ๋ฐ”์ผ ๋ธŒ๋ผ์šฐ์ €์—์„œ ํ”Œ๋Ÿฌ๊ทธ์ธ ์—†์ด ๋™์ž‘
  • ๋ณ„๋„์˜ ์•ฑ ์„ค์น˜ ์—†์ด ์›น ํ™˜๊ฒฝ์—์„œ ๋ฐ”๋กœ ๋ผ์ด๋ธŒ ์ปค๋จธ์Šค ๊ธฐ๋Šฅ ๊ตฌํ˜„ ๊ฐ€๋Šฅ

P2P ์—ฐ๊ฒฐ์„ ํ†ตํ•ด ๋Œ€์—ญํญ ์‚ฌ์šฉ ์ตœ์ ํ™”

  • ์„œ๋ฒ„ ๋ถ€ํ•˜๋ฅผ ์ค„์ด๊ณ  ๋น„์šฉ ์ ˆ๊ฐ ๊ฐ€๋Šฅ
  • ํ•„์š”์— ๋”ฐ๋ผ SFU(Selective Forwarding Unit) ๋ฐฉ์‹์„ ํ™œ์šฉํ•˜์—ฌ ๋‹ค์ˆ˜์˜ ์‹œ์ฒญ์ž๊ฐ€ ์ฐธ์—ฌ ๊ฐ€๋Šฅ

๋‹ค์ค‘ ์‚ฌ์šฉ์ž ์ŠคํŠธ๋ฆฌ๋ฐ ์ง€์› (๋ผ์ด๋ธŒ ๋ฐฉ์†ก ๋ฐ ๊ทธ๋ฃน ์ฑ„ํŒ… ๊ฐ€๋Šฅ)

  • ํŒ๋งค์ž๊ฐ€ ๋ผ์ด๋ธŒ ๋ฐฉ์†ก์„ ์†ก์ถœํ•˜๊ณ , ์—ฌ๋Ÿฌ ๋ช…์˜ ๊ณ ๊ฐ์ด ๋™์‹œ์— ์‹œ์ฒญ ๊ฐ€๋Šฅ

๋ณด์•ˆ์„ฑ ๊ฐ•ํ™” (E2E ์•”ํ˜ธํ™” ์ง€์›)

  • WebRTC๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์•”ํ˜ธํ™”(Encryption)๋ฅผ ์ ์šฉํ•˜์—ฌ ๋ณด์•ˆ์„ฑ์ด ๋›ฐ์–ด๋‚จ
  • ๋ฏผ๊ฐํ•œ ๊ณ ๊ฐ ์ •๋ณด๊ฐ€ ํฌํ•จ๋œ ์ปค๋จธ์Šค ํ™˜๊ฒฝ์—์„œ๋„ ์•ˆ์ „ํ•œ ๋ฐ์ดํ„ฐ ์ „์†ก ๊ฐ€๋Šฅ
ElasticSearch

Elasticsearch

๊ฐœ๋…

Elasticsearch๋ž€?

Apache Lucene( ์•„ํŒŒ์น˜ ๋ฃจ์”ฌ ) ๊ธฐ๋ฐ˜์˜ Java ์˜คํ”ˆ์†Œ์Šค ๋ถ„์‚ฐ ๊ฒ€์ƒ‰ ์—”์ง„์œผ๋กœ, ๋ฐฉ๋Œ€ํ•œ ์–‘์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์‹ ์†ํ•˜๊ฒŒ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ €์žฅ, ๊ฒ€์ƒ‰, ๋ถ„์„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์—˜๋ผ์Šคํ‹ฑ ์„œ์น˜๋Š” ๋‹จ๋…์œผ๋กœ ์‚ฌ์šฉ๋˜๊ธฐ๋„ ํ•˜์ง€๋งŒ, ELK( Elasticsearch / Logstatsh / Kibana )์Šคํƒ์œผ๋กœ ์‚ฌ์šฉ๋˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

Logstash : ๋‹ค์–‘ํ•œ ์†Œ์Šค( DB, csvํŒŒ์ผ ๋“ฑ )์˜ ๋กœ๊ทธ ๋˜๋Š” ํŠธ๋žœ์žญ์…˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ง‘, ์ง‘๊ณ„, ํŒŒ์‹ฑํ•˜์—ฌ Elasticsearch๋กœ ์ „๋‹ฌ

Kibana : Elasticsearch์˜ ๋น ๋ฅธ ๊ฒ€์ƒ‰์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์‹œ๊ฐํ™” ๋ฐ ๋ชจ๋‹ˆํ„ฐ๋ง

Elasticsearch

  • ์‹ค์‹œ๊ฐ„ ๊ฒ€์ƒ‰ ๋ฐ ๋ถ„์„:

    ๋ฐ์ดํ„ฐ๊ฐ€ ์ถ”๊ฐ€๋˜๊ฑฐ๋‚˜ ์ˆ˜์ •๋  ๋•Œ ๊ฑฐ์˜ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ์— ๋ฐ˜์˜๋˜์–ด, ๋น ๋ฅธ ๊ฒ€์ƒ‰ ์‘๋‹ต ์†๋„๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

  • ํ™•์žฅ์„ฑ:

    ๋ถ„์‚ฐ ์•„ํ‚คํ…์ฒ˜๋ฅผ ์ฑ„ํƒํ•˜์—ฌ ํด๋Ÿฌ์Šคํ„ฐ ๊ตฌ์„ฑ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์—ฌ๋Ÿฌ ๋…ธ๋“œ์— ๋ถ„์‚ฐ์‹œํ‚ฌ ์ˆ˜ ์žˆ์–ด, ๋ฐ์ดํ„ฐ ์–‘์ด ์ฆ๊ฐ€ํ•˜๋”๋ผ๋„ ์‹œ์Šคํ…œ ํ™•์žฅ์ด ์šฉ์ดํ•ฉ๋‹ˆ๋‹ค.

  • ๊ฐ•๋ ฅํ•œ ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ:

    ๋‹จ์ˆœ ํ…์ŠคํŠธ ๊ฒ€์ƒ‰ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ๋ณต์žกํ•œ ์ฟผ๋ฆฌ, ํ•„ํ„ฐ๋ง, ์ง‘๊ณ„(aggregations) ๊ธฐ๋Šฅ ๋“ฑ์„ ์ง€์›ํ•˜์—ฌ ๋‹ค์–‘ํ•œ ๋น„์ฆˆ๋‹ˆ์Šค ์š”๊ตฌ์‚ฌํ•ญ์— ๋งž๋Š” ๊ฒ€์ƒ‰ ์†”๋ฃจ์…˜์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์œ ์—ฐํ•œ ๋ฐ์ดํ„ฐ ๋ชจ๋ธ:

    JSON ๊ธฐ๋ฐ˜์˜ ๋ฐ์ดํ„ฐ ์ €์žฅ ๋ฐฉ์‹์„ ์ฑ„ํƒํ•ด ์Šคํ‚ค๋งˆ๊ฐ€ ์ž์œ ๋กœ์›Œ, ๋‹ค์–‘ํ•œ ํ˜•ํƒœ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์†์‰ฝ๊ฒŒ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋‹ค์–‘ํ•œ ํ™œ์šฉ ์‚ฌ๋ก€:

    ์›น์‚ฌ์ดํŠธ ๊ฒ€์ƒ‰, ๋กœ๊ทธ ๋ถ„์„, ์‹ค์‹œ๊ฐ„ ๋ชจ๋‹ˆํ„ฐ๋ง, ๋ฐ์ดํ„ฐ ๋ถ„์„ ๋“ฑ ์—ฌ๋Ÿฌ ๋ถ„์•ผ์—์„œ ํ™œ์šฉ๋˜๋ฉฐ, Kibana์™€ ๊ฐ™์€ ์‹œ๊ฐํ™” ๋„๊ตฌ์™€ ์—ฐ๊ณ„ํ•˜์—ฌ ๋ฐ์ดํ„ฐ ์ธ์‚ฌ์ดํŠธ๋ฅผ ๋„์ถœํ•˜๋Š” ๋ฐ ํšจ๊ณผ์ ์ž…๋‹ˆ๋‹ค.

nori

Elasticsearch์— ํ•œ๊ธ€ ํ˜•ํƒœ์†Œ ๋ถ„์„๊ธฐ์ธ nori๋ฅผ ์ ์šฉํ•˜์—ฌ ํ•œ๊ธ€ ๋ฌธ์„œ์˜ ์ƒ‰์ธ ๋ฐ ๊ฒ€์ƒ‰ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ ์ด์œ 

์˜์กด์„ฑ ์ถ”๊ฐ€

implementation 'org.springframework.data:spring-data-elasticsearch'

nori ํ”Œ๋Ÿฌ๊ทธ์ธ ์„ค์น˜

sudo bin/elasticsearch-plugin install analysis-nori
sudo systemctl restart elasticsearch

โ—nori๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ, ์Šคํ”„๋ง์—์„œ document.๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ด์ฃผ์ง€ ์•Š์Œ

Spring Boot Starter Mail

Spring Boot Starter Mail

Spring Boot Starter Mail์„ ํ™œ์šฉํ•ด ๊ตฌ๊ธ€ SMTP ์„œ๋ฒ„๋ฅผ ํ†ตํ•ด ์ด๋ฉ”์ผ ๋ฐœ์†ก์„ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ด€๋ฆฌ์ž๊ฐ€ ๊ตฌ๋งค์ž, ํŒ๋งค์ž์—๊ฒŒ ๋ฌธ์˜ ๋‹ต๋ณ€, ๊ด‘๊ณ  ๋“ฑ์„ ๋‹ค์–‘ํ•œ ์ƒํ™ฉ์—์„œ ์ด๋ฉ”์ผ ์ „์†ก์ด ํ•„์š”ํ•  ๋•Œ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜์กด์„ฑ ์ถ”๊ฐ€

implementation 'org.springframework.boot:spring-boot-starter-mail'

JavaMailSender : Spring Framework์—์„œ ์ œ๊ณตํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋กœ, JavaMail API๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ด๋ฉ”์ผ ๋ฐœ์†ก ๊ธฐ๋Šฅ์„ ๊ฐ„ํŽธํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ถ”์ƒํ™”ํ•œ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค. ์ฃผ๋กœ SMTP ์„œ๋ฒ„ ์„ค์ •์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฉ”์ผ์„ ์ „์†กํ•˜๋ฉฐ, ๋‹จ์ˆœ ํ…์ŠคํŠธ ๋ฉ”์ผ๋ฟ ์•„๋‹ˆ๋ผ MIME ๋ฉ”์‹œ์ง€ ์ „์†ก๋„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

JavaMailSender : JavaMailSender ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ธฐ๋ณธ ๊ตฌํ˜„์ฒด๋กœ, ์‹ค์ œ SMTP ์„œ๋ฒ„์™€์˜ ์—ฐ๊ฒฐ ์„ค์ •(ํ˜ธ์ŠคํŠธ, ํฌํŠธ, ์‚ฌ์šฉ์ž ์ธ์ฆ ๋“ฑ)์„ ๊ด€๋ฆฌํ•˜๋ฉฐ, JavaMailSender๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ด๋ฉ”์ผ ์ „์†ก์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

MimeMessageHelper : MimeMessage ๊ฐ์ฒด๋ฅผ ๋ณด๋‹ค ์‰ฝ๊ฒŒ ์ƒ์„ฑํ•˜๊ณ  ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ํ—ฌํผ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค. HTML ๋‚ด์šฉ, ์ฒจ๋ถ€ํŒŒ์ผ, ์ธ๋ผ์ธ ์ด๋ฏธ์ง€ ๋“ฑ ๋ณต์žกํ•œ ๋ฉ”์ผ ๋ฉ”์‹œ์ง€ ๊ตฌ์„ฑ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ, ๋‹ค์–‘ํ•œ ํŽธ์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•˜์—ฌ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ณต์žกํ•œ MIME ๋ฉ”์‹œ์ง€๋ฅผ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ” ๋ฐฐํฌ Script

๐Ÿ‘€ UI/UX ๋‹จ์œ„ ๊ฒฐ๊ณผ์„œ

๐Ÿ‘ค ์‡ผํ•‘๋ชฐ ์ด์šฉ์ž ๊ด€๋ จ ๊ธฐ๋Šฅ

1. ๋กœ๊ทธ์ธ

๐ŸŽฌ

social_login

  • ์‡ผํ•‘๋ชฐ ์ž์ฒด ํšŒ์› ๋กœ๊ทธ์ธ
  • ์†Œ์…œ ๋กœ๊ทธ์ธ

2. ์ƒํ’ˆ ๊ตฌ๋งค

๐ŸŽฌ ![buy_items](./exec/userGif/PurchaseGoods.gif)
  • Query DSL์„ ์ด์šฉํ•œ ๋ฒ ์ŠคํŠธ ์ƒํ’ˆ
  • ์ƒํ’ˆ ๊ฒ€์ƒ‰
    ๐Ÿ–ผ๏ธ ![search_item](./exec/userImage/์ƒํ’ˆ๊ฒ€์ƒ‰.png)
  • ์นดํ…Œ๊ณ ๋ฆฌ ๋ณ„ ์ƒํ’ˆ
    ๐Ÿ–ผ๏ธ ![category_item](./exec/userImage/์นดํ…Œ๊ณ ๋ฆฌ๋ณ„%20์ƒํ’ˆ%20ํ™•์ธ.png)
  • ์žฅ๋ฐ”๊ตฌ๋‹ˆ - ์ˆ˜๋Ÿ‰ ๋ณ€๊ฒฝ, ์ œ๊ฑฐ
  • ๊ฒฐ์ œ - ๋ฐฐ์†ก์ง€, ํฌ์ธํŠธยท์ฟ ํฐ ์ ์šฉ, ํฌํŠธ์› API

3. ๋ผ์ด๋ธŒ ์ปค๋จธ์Šค

๐ŸŽฌ ![live_shopping](./exec/userGif/๋ผ์ด๋ธŒ์ปค๋จธ์Šค.gif)
  • ๋ผ์ด๋ธŒ ์ปค๋จธ์Šค ์‹œ์ฒญ ๋ฐ ์ฑ„ํŒ… ๊ธฐ๋Šฅ
  • ํŒ๋งค ์ค‘ ์ƒํ’ˆ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋‹ด๊ธฐ - ๊ฐœ๋ณ„, ์ „์ฒด

4. ์‹๋‹จ ๊ด€๋ฆฌ

๐ŸŽฌ ![calendar](./exec/userGif/DietManagement.gif)
  • ์ด์šฉ์ž ํ‚ค, ๋ชธ๋ฌด๊ฒŒ ์ •๋ณด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ํ•œ ์ผ์ผ ๊ถŒ์žฅ ์นผ๋กœ๋ฆฌ ๊ณ„์‚ฐ
  • ์บ˜๋ฆฐ๋”๋ฅผ ์ด์šฉํ•œ ์ผ์ผ ์‹๋‹จ ๋“ฑ๋ก
  • ๊ถŒ์žฅ ์นผ๋กœ๋ฆฌ ์ด์ƒ ์„ญ์ทจ์‹œ ๊ฒฝ๊ณ  ํ‘œ์‹œ

5. ๋ ˆ์‹œํ”ผ

๐ŸŽฌ ![recipe](./exec/userGif/Recipe.gif)
  • ๋งˆ์ดํŽ˜์ด์ง€์—์„œ ๋‚ด ๋ ˆ์‹œํ”ผ ํ™•์ธ ๋ฐ ์ž‘์„ฑ
  • ๋ ˆ์‹œํ”ผ ํŽ˜์ด์ง€์—์„œ ์ „์ฒด ๋ ˆ์‹œํ”ผ ํ™•์ธ
  • ๋ ˆ์‹œํ”ผ ์ƒ์„ธ์—์„œ ๊ด€๋ จ ์ƒํ’ˆ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋‹ด๊ธฐ

6. ๊ธฐํƒ€

  • ๋งˆ์ดํŽ˜์ด์ง€-์ •๋ณด๊ด€๋ฆฌ
    ๐ŸŽฌ ![mypage-info](./exec/userImage/๋งˆ์ดํŽ˜์ด์ง€-๊ฐœ์ธ์ •๋ณด์ˆ˜์ •.png) ![mypage-address](./exec/userImage/๋งˆ์ดํŽ˜์ด์ง€-๋ฐฐ์†ก์ง€๊ด€๋ฆฌ.png)
  • ๋งˆ์ดํŽ˜์ด์ง€-์ƒํ’ˆ๊ด€๋ จ(์ฃผ๋ฌธ๋‚ด์—ญ, ํ›„๊ธฐ ๋“ฑ)
    ๐Ÿ–ผ๏ธ ![mypage-order](./exec/userImage/๋งˆ์ดํŽ˜์ด์ง€-์ฃผ๋ฌธ๋‚ด์—ญ.png) ![mypage-review](./exec/userImage/๋งˆ์ดํŽ˜์ด์ง€-์ƒํ’ˆํ›„๊ธฐ.png)
  • ๊ณ ๊ฐ์„ผํ„ฐ(FAQ, ๊ณต์ง€์‚ฌํ•ญ, ๋ฌธ์˜)
    ๐Ÿ–ผ๏ธ ![board-faq](./exec/userImage/๊ณ ๊ฐ์„ผํ„ฐ-FAQ.png) ![board-question](./exec/userImage/๊ณ ๊ฐ์„ผํ„ฐ-๋ฌธ์˜ํ•˜๊ธฐ.png)

๐Ÿช ์‡ผํ•‘๋ชฐ ํŒ๋งค์ž ์ฃผ์š” ๊ธฐ๋Šฅ

1. ๋กœ๊ทธ์ธ

๐ŸŽฌ ![seller_login]](./exec/sellerGif/ํšŒ์›๊ฐ€์ž…๋ฐ๋กœ๊ทธ์ธ.gif)
  • ํŒ๋งค์ž ๊ณ„์ • ๋กœ๊ทธ์ธ
  • ์ธ์ฆ ๋ฐ ๊ถŒํ•œ ๊ด€๋ฆฌ

2. ์ƒํ’ˆ ๊ด€๋ฆฌ

๐ŸŽฌ ![item](./exec/sellerGif/์ƒํ’ˆ๋“ฑ๋ก ๋ฐ ์กฐํšŒ.gif)
  • ์ƒํ’ˆ ๋“ฑ๋ก ๋ฐ ์ˆ˜์ •
  • ์ƒํ’ˆ ๋ชฉ๋ก ์กฐํšŒ ๋ฐ ๊ฒ€์ƒ‰
  • ์ƒํ’ˆ ์‚ญ์ œ

3. ์ฃผ๋ฌธ ๋ฐ ๋ฐฐ์†ก ๊ด€๋ฆฌ

๐ŸŽฌ ![order](./exec/sellerGif/์ฃผ๋ฌธ์กฐํšŒ.gif)
  • ์ฃผ๋ฌธ ๋‚ด์—ญ ํ™•์ธ ๋ฐ ์ฒ˜๋ฆฌ
  • ๋ฐฐ์†ก ์ƒํƒœ ๋ณ€๊ฒฝ ๋ฐ ์ถ”์ 
  • ์ฃผ๋ฌธ ์ทจ์†Œ ๋ฐ ํ™˜๋ถˆ ๊ด€๋ฆฌ

4. ๋ผ์ด๋ธŒ ์ปค๋จธ์Šค ์šด์˜

๐ŸŽฌ ![cast](./exec/sellerGif/๋ผ์ด๋ธŒ์‹ ์ฒญ๋ฐ๋ฐฉ์†ก์†ก์ถœ.gif)
๐ŸŽฌ ![cast](./exec/sellerGif/๋ฐฉ์†ก์†ก์ถœํ™”๋ฉด.gif)
  • ๋ผ์ด๋ธŒ ์ปค๋จธ์Šค ์ง„ํ–‰
  • ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ… ์ง€์›
  • ํŒ๋งค ์ค‘ ์ƒํ’ˆ ์ถ”๊ฐ€ ๋ฐ ๊ด€๋ฆฌ

5. ํŒ๋งค ํ†ต๊ณ„

๐ŸŽฌ ![statistics](./exec/sellerGif/ํŒ๋งค ํ†ต๊ณ„.gif)
  • ์ผ๋ณ„/์ฃผ๋ณ„/์›”๋ณ„ ํŒ๋งค๋Ÿ‰ ๋ถ„์„
  • ๋ฒ ์ŠคํŠธ์…€๋Ÿฌ ์ƒํ’ˆ ํ™•์ธ
  • ๋งค์ถœ ๋ฐ์ดํ„ฐ ์‹œ๊ฐํ™”

6. ๊ธฐํƒ€

๐ŸŽฌ ![seller](./exec/sellerGif/ํšŒ์‚ฌ๊ณ„์ •๊ด€๋ฆฌ๋ฆฌ.gif)
  • ํŒ๋งค์ž ๋งˆ์ดํŽ˜์ด์ง€ - ์ •๋ณด ์ˆ˜์ •

  • ๊ณ ๊ฐ ๋ฌธ์˜ ๊ด€๋ฆฌ

๐Ÿ‘ฎ ์‡ผํ•‘๋ชฐ ๊ด€๋ฆฌ์ž ๊ด€๋ จ ๊ธฐ๋Šฅ

๐ŸŽฌ

๋ฐฅ์ด์Šˆ ๊ด€๋ฆฌ์žํŽ˜์ด์ง€ ์†Œ๊ฐœ

1. ํšŒ์›๊ด€๋ฆฌ(1) - ์ด์šฉ์ž

๐ŸŽฌ ![ํšŒ์›์ •๋ณด๊ด€๋ฆฌ](./exec/admin-images/ํšŒ์›์ •๋ณด๊ด€๋ฆฌ.gif)
  • ํšŒ์› ์ƒํƒœ๊ด€๋ฆฌ(ํ™œ์„ฑ/๋น„ํ™œ์„ฑ)
  • ํšŒ์› ์ƒ์„ธ์ •๋ณด ๊ด€๋ฆฌ

2. ํšŒ์›๋“ฑ๋ก

๐ŸŽฌ ![์—‘์…€์ผ๊ด„๋“ฑ๋ก](./exec/admin-images/์—‘์…€์ผ๊ด„๋“ฑ๋ก.gif)
  • ์—‘์…€ ์ผ๊ด„๋“ฑ๋ก
    • ์—‘์…€ํŒŒ์ผ ํ…œํ”Œ๋ฆฟ ๋‹ค์šด๋กœ๋“œ ์ดํ›„ ๋ชฉ๋ก ์—…๋ฐ์ดํŠธ ํ•˜์—ฌ ๋“ฑ๋ก

3. ํšŒ์› ๋ฉ”์ผ ๋ฐœ์†ก

๐ŸŽฌ ![ํšŒ์›๋ฉ”์ผ๋ฐœ์†ก](./exec/admin-images/ํšŒ์›๋ฉ”์ผ๋ฐœ์†ก.gif)
  • ํšŒ์› ๋Œ€์ƒ ๋ฉ”์ผ๋ฐœ์†ก (์„ ํƒ/์ „์ฒด ๋ฐœ์†ก)

4. ํšŒ์›๊ด€๋ฆฌ(2) - ํŒ๋งค์ž

๐ŸŽฌ ![ํŒ๋งค์ž๊ด€๋ฆฌ](./exec/admin-images/ํŒ๋งค์ž๊ด€๋ฆฌ.gif)
  • ํŒ๋งค์ž ์ƒํƒœ๊ด€๋ฆฌ(ํ™œ์„ฑ/๋น„ํ™œ์„ฑ)
  • ํŒ๋งค์ž ์ƒ์„ธ์ •๋ณด ๊ด€๋ฆฌ
  • ํŒ๋งค๊ถŒํ•œ ์Šน์ธ ์ ˆ์ฐจ

5. ํŒ๋งค์ž ํŠธ๋ฆฌ๊ตฌ์กฐ

๐ŸŽฌ ![ํŒ๋งค์ž ํŠธ๋ฆฌ๊ตฌ์กฐ](./exec/admin-images/ํŒ๋งค์ž%20ํŠธ๋ฆฌ๊ตฌ์กฐ.png)
  • ์ถ”๊ฐ€๊ณ„์ • ์ง€๊ธ‰ ์—ฌ๋ถ€์— ๋”ฐ๋ฅธ ๊ณ„์ • ํ˜„ํ™ฉ ํŒŒ์•…

6. ์ฃผ๋ฌธ ํ˜„ํ™ฉ

๐ŸŽฌ ![์ฃผ๋ฌธํ˜„ํ™ฉ](./exec/admin-images/์ฃผ๋ฌธํ˜„ํ™ฉ.gif)
  • ์‡ผํ•‘๋ชฐ ์ฃผ๋ฌธ ํ˜„ํ™ฉ ๊ฒ€์ƒ‰ ๋ฐ ์ƒ์„ธ ๊ด€๋ฆฌ

7. ๋ผ์ด๋ธŒ์ปค๋จธ์Šค ๊ด€๋ฆฌ

๐ŸŽฌ ![๋ผ์ด๋ธŒ์ปค๋จธ์Šค๊ด€๋ฆฌ](./exec/userGif/๋ผ์ด๋ธŒ์ปค๋จธ์Šค.gif)
  • ๋ผ์ด๋ธŒ ์ปค๋จธ์Šค ์‹ ์ฒญ์‹œ ๋‚ด๋ถ€ ๊ธฐ์ค€์— ๋”ฐ๋ผ ์Šน์ธ/๋ฐ˜๋ ค
  • ์Šน์ธ์‹œ ๋ผ์ด๋ธŒ ์˜ˆ์ • ์บ˜๋ฆฐ๋”์— ๋“ฑ๋ก ๋ฐ ๊ด€๋ฆฌ
  • ๋ผ์ด๋ธŒ ๋ชจ๋‹ˆํ„ฐ๋ง ๋ฐ ์ข…๋ฃŒ ๊ธฐ๋Šฅ

8. ์‡ผํ•‘๋ชฐ ๋ถ„์„ - ํ†ต๊ณ„

๐ŸŽฌ - Query DSL API๋ฅผ ํ™œ์šฉํ•˜์—ฌ ํ†ต๊ณ„ ๋ถ„์„ ํŽ˜์ด์ง€ ์ œ๊ณต ![์ฟผ๋ฆฌdslํ†ต๊ณ„](./exec/admin-images/์ฟผ๋ฆฌdslํ†ต๊ณ„.gif)
  • ํŒ๋งค์ž ํ†ต๊ณ„
  • ๋งค์ถœ ๋ถ„์„
  • ์นดํ…Œ๊ณ ๋ฆฌ ๋ถ„์„
  • ์‹œ๊ฐ„๋Œ€๋ณ„ ๋ถ„์„
  • ์œ ์ € ํ†ต๊ณ„
  • ์žฌ๊ตฌ๋งค์œจ ๋ถ„์„

9. ๊ธฐํƒ€

  • ์นดํ…Œ๊ณ ๋ฆฌ ๊ด€๋ฆฌ

    • ์‡ผํ•‘๋ชฐ ํŒ๋งค ์นดํ…Œ๊ณ ๋ฆฌ ์ถ”๊ฐ€ ๋ฐ ์œ ์ง€๋ณด์ˆ˜
  • CS ๊ด€๋ฆฌ

    • ์ด์šฉ์ž ๋Œ€์ƒ ๊ณต์ง€ ๋ฐ ๋ฌธ์˜์‚ฌํ•ญ ๊ด€๋ฆฌ
  • ๊ธฐํƒ€ ๋“ฑ๋“ฑ

๐Ÿฅ— ์†Œ๊ฐ

๊น€์ง€ํ•œ

์‡ผํ•‘๋ชฐ ์‹œ์Šคํ…œ์ด ์˜ˆ์ƒ๋ณด๋‹ค ํ›จ์”ฌ ๋ณต์žกํ•˜๊ณ  ์กฐ์œจํ•  ์š”์†Œ๊ฐ€ ๋งŽ๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ฌ์•˜์Šต๋‹ˆ๋‹ค. ํŒ€์žฅ์œผ๋กœ์„œ ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๋ฉฐ ํ”„๋กœ์ ํŠธ๋ฅผ ์ด๋Œ์—ˆ๊ณ , ๋ฐฐํฌ์™€ ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์„ ์ง์ ‘ ๊ฒฝํ—˜ํ•˜๋ฉฐ ๊ธฐ์ˆ ์  ์ดํ•ด๋„๋ฅผ ๋†’์ผ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ˆ๋‹ค. ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์„ฑ๊ณต์ ์œผ๋กœ ๊ตฌํ˜„ํ•˜๋ฉฐ ํ•œ์ธต ์„ฑ์žฅํ•  ์ˆ˜ ์žˆ์—ˆ๋˜ ๊ฐ’์ง„ ๊ฒฝํ—˜์ด์—ˆ์Šต๋‹ˆ๋‹ค.

์ด๋‹ค์€

๋‹จ์ˆœํ•œ CRUD ๊ฐœ๋ฐœ์„ ๋„˜์–ด ์„œ๋น„์Šค ์šด์˜์— ์ตœ์ ํ™”๋œ ์‹œ์Šคํ…œ ๊ตฌ์ถ•์„ ๊ณ ๋ฏผํ•˜๋ฉฐ, React์™€ Redux๋ฅผ ํ™œ์šฉํ•ด 48๊ฐœ์˜ ๊ด€๋ฆฌ์ž ํŽ˜์ด์ง€๋ฅผ ๊ฐœ๋ฐœํ•ด๋ณผ ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์ตœ์ข… ๋ฐœํ‘œ๋ฅผ ์ค€๋น„ํ•˜๋ฉฐ ์šฐ๋ฆฌ ํ”„๋กœ์ ํŠธ๋ฅผ ๋˜์งš์–ด ๋ณด๊ณ , ๋ฐ์ดํ„ฐ ํ๋ฆ„๊ณผ API ์„ค๊ณ„๊นŒ์ง€ ๊นŠ์ด ์ดํ•ดํ•˜๊ณ ์ž ๋…ธ๋ ฅํ•˜์˜€๋‹ค.

๊ฐ•ํ˜„ํ˜ธ

๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์„ ์ฒ˜์Œ ์ ‘ํ•˜๋ฉด์„œ ์‡ผํ•‘๋ชฐ ํ”Œ๋žซํผ์„ ๊ตฌํ˜„ํ•˜๋Š” ์ด๋ฒˆ ํ”„๋กœ์ ํŠธ๋Š” ํ™”๋ฉด์—์„œ ๋ณด์ด๋Š” ๋‹จ์ˆœํ•œ ๊ธฐ๋Šฅ๋“ค ๋’ค์— ์ด๋ ‡๊ฒŒ ๋ณต์žกํ•œ ๋กœ์ง๊ณผ ๊ตฌ์กฐ๊ฐ€ ์ˆจ์–ด์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์— ๋†€๋ž์Šต๋‹ˆ๋‹ค. ์ฒ˜์Œ์—๋Š” ๋‚ฏ์„ค์—ˆ๋˜ ๊ธฐ์ˆ  ์Šคํƒ๋“ค์„ ํ•˜๋‚˜์”ฉ ์ตํžˆ๊ณ  ์ ์šฉํ•ด๊ฐ€๋Š” ๊ณผ์ •์—์„œ ๋งŽ์€ ์‹œํ–‰์ฐฉ์˜ค๋ฅผ ๊ฒช์—ˆ์ง€๋งŒ, ๊ฒฐ๊ณผ์ ์œผ๋กœ ์•ˆ์ •์ ์ธ ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ์—ˆ๋˜ ์ ์ด ๊ฐ€์žฅ ๋ณด๋žŒ์ฐผ์Šต๋‹ˆ๋‹ค.

๊น€์ง€์›

์ฒ˜์Œ ์ปจ์„คํ„ดํŠธ๋‹˜๊ป˜์„œ ์‡ผํ•‘๋ชฐ์ด ๊ต‰์žฅํžˆ ํฐ ๊ทœ๋ชจ์˜ ํ”„๋กœ์ ํŠธ๋ผ๊ณ  ๋ง์”€ํ•˜์…จ์„ ๋•Œ๋Š” ์‹ค๊ฐํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ธฐํš์„ ํ•˜๊ณ  ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ ์˜ˆ์ƒํ–ˆ๋˜ ๊ฒƒ๋ณด๋‹ค ์ ์  ํ•  ์ผ์ด ๋งŽ์•„์ง€๊ณ  ๊ทœ๋ชจ๊ฐ€ ์ปค์ง€๋Š” ๊ฒƒ์„ ๋ณด๋ฉฐ, 6๋ช…์ด์„œ 6์ฃผ ๋™์•ˆ ์ด ํ”„๋กœ์ ํŠธ๋ฅผ ์™„์ˆ˜ํ–ˆ๋‹ค๋Š” ์„ฑ์ทจ๊ฐ์„ ๋А๋‚„ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ, ํ‰์†Œ์— ์ต์ˆ™ํ–ˆ๋˜ ๊ฒƒ๋“ค์ด ๋ณด์ด์ง€ ์•Š๋Š” ๋ถ€๋ถ„๊นŒ์ง€ ์„ธ์‹ฌํ•˜๊ฒŒ ๊ณ ๋ ค๋˜์–ด ๋งŒ๋“ค์–ด์กŒ๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ฌ์œผ๋ฉฐ, ๊ธฐํš์˜ ์ค‘์š”์„ฑ๊ณผ ํŒ€์›๋“ค๊ณผ ์˜๊ฒฌ์„ ๋‚˜๋ˆ„๋Š” ๊ณผ์ •์ด ๋งค์šฐ ์ค‘์š”ํ•˜๋‹ค๋Š” ์ ์„ ๋‹ค์‹œ๊ธˆ ์‹ค๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.

์œค๊ฒฝ์ƒ

์ด๋ฒˆ ํ”„๋กœ์ ํŠธ๋ฅผ ํ†ตํ•ด ๋ฆฌ์•กํŠธ์˜ ๊ธฐ๋ณธ ๊ฐœ๋…์„ ์ตํžˆ๊ณ , ํ˜‘์—…์˜ ์ค‘์š”์„ฑ์„ ๊ฒฝํ—˜ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์•ž์œผ๋กœ๋Š” ๋”์šฑ ์›ํ™œํ•œ ํ˜‘์—…์„ ์œ„ํ•ด ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜์„ ๊ฐ•ํ™”ํ•˜๊ณ , ์ฝ”๋“œ ์ž‘์„ฑ ์‹œ ํŒ€์›๋“ค๊ณผ์˜ ์กฐ์œจ์„ ์‹ ๊ฒฝ ์“ฐ๋ฉฐ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค

๊น€๊ฒฝ์€

๊ทœ๋ชจ๊ฐ€ ์ปธ๋˜ ํ”„๋กœ์ ํŠธ์˜€๋˜ ๋งŒํผ CRUD๊ฐ€ ๋งŽ์•„์„œ ํž˜๋“ค์—ˆ์ง€๋งŒ, ๋•๋ถ„์— ์Šคํ”„๋ง๊ณผ ๊นƒ์— ๋Œ€ํ•œ ์ดํ•ด๋„๊ฐ€ ๋†’์•„์กŒ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ, ์‡ผํ•‘๋ชฐ ๊ฐœ๋ฐœ์„ ์ง„ํ–‰ํ•˜๋ฉฐ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•˜๋‹ค๋Š” ์ ์„ ๊นจ๋‹ฌ์•˜๊ณ , ๊ตฌํ˜„ ๊ณผ์ •์—์„œ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๊ธฐ๋Šฅ๋“ค์ด ์ถ”๊ฐ€์ ์œผ๋กœ ์š”๊ตฌ๋˜์–ด ์–ด๋ ค์›€์ด ์žˆ์—ˆ์ง€๋งŒ, ํŒ€์›๋“ค๊ณผ์˜ ํ˜‘์—…์„ ํ†ตํ•ด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ํ˜‘์—…์˜ ์ค‘์š”์„ฑ์„ ๋‹ค์‹œ ํ•œ๋ฒˆ ์‹ค๊ฐํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๐Ÿฅ— ์ฒจ๋ถ€์ž๋ฃŒ

๋ฐœํ‘œ ์ž๋ฃŒ

[๋ฐœํ‘œ์ž๋ฃŒ ๋ณด๊ธฐ](./exec/[SSAFY] ๊ณตํ†ตํ”„๋กœ์ ํŠธ C108 ์ตœ์ข…๋ฐœํ‘œ PPT.pdf)

UCC

Video Label

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 7