์ง€๋ผ ๋„์ž… ์ œ์•ˆ์„œ

์ง€๋ผ๋ฅผ ์ง€๊ธˆ๊นŒ์ง€ ์‚ฌ์šฉํ•ด์˜ค์ง€ ์•Š์•˜๋˜ ์ด์œ , ๊ทธ๋ฆฌ๊ณ  ์ด์ œ ๋„์ž…์„ ์ œ์•ˆํ•˜๋Š” ์ด์œ ๋ฅผ ์ •๋ฆฌํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ํŒ€์ด ์ œ ์ƒ๊ฐ์— ์ถฉ๋ถ„ํžˆ ๊ณต๊ฐํ•œ๋‹ค๋ฉด, ํŒ€์— ๋„์ž…ํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค.

๋ถ€๋™์‚ฐ ๊ฒฝ๋งค ๊ณต๋ถ€ ์‹œ์ž‘

๋Œ€ํ•™์ƒ ๋•Œ ์–ด๋จธ๋‹ˆ๊ฐ€ ๋ถ€๋™์‚ฐ ๊ฒฝ๋งค ์ฑ…์„ ์ฝ์–ด๋ณด๋ผ๋ฉฐ ๊ฑด๋‚ด์ฃผ์…จ๋˜ ๊ธฐ์–ต์ด ๋‚ฉ๋‹ˆ๋‹ค. ๊ทธ ์ฑ…์„ ๋ฐ˜์ •๋„ ์ฝ๋‹ค๊ฐ€ ๋ฎ์–ด๋ฒ„๋ ธ๋Š”๋ฐ ๋งŒ์•ฝ ๊ทธ ๋•Œ๋ถ€ํ„ฐ ์ž‘๊ฒŒ๋ผ๋„ ํ–‰๋™์„ ํ–ˆ๋‹ค๋ฉด... ์‹ญ๋…„์ด ๋„˜๊ฒŒ ์ง€๋‚œ ์ง€๊ธˆ ์ €๋Š” ์–ด๋–ค ๋ชจ์Šต์ผ๊นŒ์š”? ๋ถ€๋™์‚ฐ ๊ฒฝ๋งค๋ฅผ ์‹œ์ž‘ํ•˜๊ธฐ ์•ž์„œ ์ง€๊ธˆ๊นŒ์ง€ ๋ถ€๋™์‚ฐ ๊ฒฝ๋งค์— ๋Œ€ํ•œ ์ œ ์ƒ๊ฐ์„ ์ •๋ฆฌํ•ด๋ด…๋‹ˆ๋‹ค.

๋„ํ์‚ฌ์šฐ๋ฅด์Šค์—์„œ ์ด๋ฏธ์ง€ ์ฒจ๋ถ€ํ•˜๊ธฐ

์ด์ „์— ์ž‘์„ฑํ–ˆ๋˜ ๊ธ€๋“ค์— ์ฒจ๋ถ€ํ•œ ์ด๋ฏธ์ง€๊ฐ€ ๊นจ์ง€๋Š” ํ˜„์ƒ์ด ์ผ์–ด๋‚˜๋Š” ์ด์œ ์™€ ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๊ณผ์ •์„ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค.

ํŠน์ • ํŒŒ๋“œ์— ํŠธ๋ž˜ํ”ฝ์ด ๋ชฐ๋ฆฌ๋Š” ํ˜„์ƒ ์ด์œ ์™€ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

์šด์˜์ค‘์ธ ์„œ๋น„์Šค์˜ ๋ชจ๋‹ˆํ„ฐ๋ง์„ ๊ณ ๋„ํ™”ํ•˜๋˜ ์ค‘ ํŠน์ • ํŒŒ๋“œ์—๋งŒ ๋ฆฌ์†Œ์Šค๊ฐ€ ๋ชฐ๋ฆฌ๋Š” ํ˜„์ƒ์„ ๋ฐœ๊ฒฌํ•˜์—ฌ ๊ทธ ์ด์œ ์™€ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๋ฆฌ์„œ์น˜๋ฅผ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค.

ํ•ด์™ธ์ฃผ์‹ ํฌํŠธํด๋ฆฌ์˜ค ๊ณต๊ฐœ 9์›” 2์ฃผ์ฐจ

๊ฐœ์š”#

์ง€๊ธˆ ํ˜„์‹œ์ ์— ์ œ๊ฐ€ ๊ฐ€์ง„ ํ•ด์™ธ์ฃผ์‹ ํฌํŠธํด๋ฆฌ์˜ค์™€ ์–ด๋–ค ์ƒ๊ฐ์œผ๋กœ ํ•ด์™ธ์ฃผ์‹์„ ํ•ด์™”์œผ๋ฉฐ, ์•ž์œผ๋กœ์˜ ๊ณ„ํš์€ ๋ฌด์—‡์ธ์ง€ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค.

ํฌํŠธํด๋ฆฌ์˜ค๋ฅผ ๊ณต๊ฐœํ•˜๋Š” ์ด์œ ์™€ ์ฃผ์˜์‚ฌํ•ญ#

์ œ๊ฐ€ ํฌํŠธํด๋ฆฌ์˜ค๋ฅผ ๊ณต๊ฐœํ•˜๋Š” ์ด์œ ๋Š” ์•„์ด๋Ÿฌ๋‹ˆํ•˜๊ฒŒ๋„ ๊ทธ ๋™์•ˆ ํฌํŠธํด๋ฆฌ์˜ค๊ฐ€ ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋ธ”๋กœ๊ทธ์— ์ •๊ธฐ์ ์œผ๋กœ ํฌํŠธํด๋ฆฌ์˜ค๋ฅผ ๊ณต๊ฐœํ•˜์ž๋Š” ๊ฒฐ์‹ฌ์€ ํฌํŠธํด๋ฆฌ์˜ค๋ฅผ ๋งŒ๋“ค์–ด์„œ ๊ด€๋ฆฌํ•˜์ž. ๋ผ๋Š” ๊ฒฐ์‹ฌ์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ํ™•์žฅํŒ์ธ ์…ˆ์ด์ฃ .

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

์ €๋Š” ํŠธ๋ ˆ์ด๋”๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ์ข…๋ชฉ์„ ๊ธฐ์ˆ ์ ์œผ๋กœ ๋ถ„์„ํ•˜๋Š” ํˆฌ์ž์ž๋„ ์•„๋‹ˆ์ฃ . ๊ฒฝ์ œ ๊ด€๋ จ ๋‰ด์Šค ๊ธฐ์‚ฌ๋‚˜ ์œ ํŠœ๋ธŒ ์˜์ƒ์„ ํ†ตํ•ด ๊พธ์ค€ํžˆ ๊ณต๋ถ€๋Š” ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค๋งŒ, ์ œ๊ฐ€ ๊ด€์‹ฌ์žˆ๋Š” ๋ถ„์•ผ๋‚˜ ์ข…๋ชฉ ์•ˆ์—์„œ ๊ฒ€์ƒ‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‹œ์•ผ๋„ ํ•œ์ •์ ์ž…๋‹ˆ๋‹ค. ์ฆ‰ ์ œ๊ฐ€ ์•ž์œผ๋กœ ์ด ๊ณต๊ฐ„์— ์ ๋Š” ์–ด๋– ํ•œ ํˆฌ์ž๊ด€๋ จ ๊ธ€์€ ์ข…๋ชฉ์ถ”์ฒœ์ด๋‚˜ ํˆฌ์ž ๊ถŒ์œ ๊ฐ€ ์•„๋‹˜์„ ๋ช…์‹œํ•ฉ๋‹ˆ๋‹ค.

ํฌํŠธํด๋ฆฌ์˜ค ๊ณต๊ฐœ#

๊ฒฝ์ œ์  ์ž์œ .png

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

ํ‰๊ฐ€๊ธˆ์•ก๊ฐ€์น˜๋กœ ๋ณด์•˜์„ ๋•Œ 300๋‹ฌ๋Ÿฌ ์•„๋ž˜์— ์žˆ๋Š” ์ข…๋ชฉ๋“ค์€ ๋งค์ˆ˜๋ฅผ ์œ„ํ•œ ๋ถ€ํ‘œ๋กœ ์‚ฌ๋†“์€ ๊ฒƒ๋“ค์ž…๋‹ˆ๋‹ค. ์‚ฌ๊ณ  ์‹ถ์€๋ฐ ๋„ˆ๋ฌด ์˜ฌ๋ž๋‹ค๊ณ  ์ƒ๊ฐ๋ผ์„œ ๊ณ„์† ๋งค์ˆ˜ ํƒ€์ด๋ฐ๋งŒ ์žฌ๋˜ ๋†ˆ๋“ค์ด์ฃ . ๊ทธ๋ฆฌ๊ณ  ๊ทธ ๋งค์ˆ˜ ํƒ€์ด๋ฐ์€ ๋ช‡ ์ฃผ๊ฐ€ ์ง€๋‚˜๋„ ์˜ค์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค... ์กฐ์ •์„ ๊ธฐ๋‹ค๋ฆฌ๋˜ ์–ด๋Š ๋‚  ์—ญ์‹œ๋‚˜ ๋น„์‹ธ๋‹ค๊ณ  ์ƒ๊ฐ๋˜์—ˆ์ง€๋งŒ ๊ทธ๋ƒฅ ์‹œ์žฅ๊ฐ€๋กœ 30-40๋งŒ์› ๊ธ์—ˆ์Šต๋‹ˆ๋‹ค. ์ œ๊ฐ€ ์‚ฐ ๊ฐ€๊ฒฉ๋Œ€๋น„ํ•ด์„œ ์ˆ˜์ต๋ฅ ์ด ํฌ๊ฒŒ ๋งˆ์ด๋„ˆ์Šค๊ฐ€ ๋˜์—ˆ์„ ๋•Œ ์‚ด ์ƒ๊ฐ์œผ๋กœ์š”. ๊ทธ๋Ÿฐ๋ฐ ๊ทธ๋ ‡๊ฒŒ ์†Œ๋Ÿ‰ ์‚ฐ ์ข…๋ชฉ๋“ค์ด ํ…Œ์Šฌ๋ผ๋ณด๋‹ค ์ˆ˜์ต๋ฅ ์ด ๋†’๋„ค์š”. ์ฐธโ€ฆ

์ง€๊ธˆ๊นŒ์ง€ ํˆฌ์ž ์›์น™?#

๋”ฑํžˆ ํˆฌ์ž ์›์น™์„ ์ •ํ•œ ์ ์€ ์—†์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋Œ€๋žต์ ์œผ๋กœ ์•„๋ž˜ ํ•ญ๋ชฉ๋“ค์„ ์ƒ๊ฐํ•˜๋ฉด์„œ ์‚ฌ๊ฑฐ๋‚˜ ํŒ”์•˜๋˜ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ํ˜์‹ ์ ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋Š” ์ œํ’ˆ์ด๋‚˜ ๊ธฐ์—… ๋ฐฉํ–ฅ์„ฑ์ด ๊ณต๊ฐœ๋˜๋ฉด ์‚ฐ๋‹ค.
    • ํ…Œ์Šฌ๋ผ, ๋งˆ์ดํฌ๋กœ์†Œํ”„ํŠธ, ํ€„์ปด, ๋””์ฆˆ๋‹ˆ
  • ๋‚ด๊ฐ€ ์‚ฌ์šฉํ•˜๋ฉด์„œ ์ข‹์•„ํ•˜๋Š” ์ œํ’ˆ, ์ž์ฃผ ์†Œ๋น„ํ•˜๋Š” ์ œํ’ˆ์„ ๊ฐ€์ง„ ๊ธฐ์—…์„ ์‚ฐ๋‹ค.
    • ์ฝ”์นด์ฝœ๋ผ, ์ฟ ํŒก, ๋ฐ์ดํ„ฐ๋…, ์œ ๋‹ˆํ‹ฐ
  • ํŽ€๋”๋ฉ˜ํƒˆ์ด ํ”๋“ค๋ฆฌ์ง€ ์•Š์€ ๊ธฐ์—…์ด ์ตœ๊ณ ๊ฐ€ ๋Œ€๋น„ ํ•˜๋ฝ์ด ํด ๋•Œ ์‚ฐ๋‹ค.
    • ํ…Œ์Šฌ๋ผ
  • ๋” ์ข‹์€ ํˆฌ์žํ•  ๊ณณ์ด ์ƒ๊ฒผ๋Š”๋ฐ ํ˜„๊ธˆ์ด ์—†์œผ๋ฉด ํŒ๋‹ค.

๋‚ด๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์ƒ๊ฐ#

์ €๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ์ƒ๊ฐ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒ๊ฐ์€ ๋งค์ผ๋งค์ผ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ์ง€๋งŒ, ์ง€๊ธˆ๊นŒ์ง€ ๋˜ ์•ž์œผ๋กœ๋„ ์ด๋Ÿฐ ์ƒ๊ฐ์— ๊ธฐ๋ฐ˜ํ•˜์—ฌ ํˆฌ์ž๋ฅผ ํ•  ์ƒ๊ฐ์ž…๋‹ˆ๋‹ค.

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

์•ž์œผ๋กœ์˜ ๊ณ„ํš#

  • ์ตœ๊ทผ์— ์ฝ์€ Tesla: Sometimes A Great Company Isn't A Great Stock ์ด๋ผ๋Š” ๊ธ€์€ ์ƒ๋‹น ๋ถ€๋ถ„ ๊ณต๊ฐํ•ฉ๋‹ˆ๋‹ค. ์œ„๋Œ€ํ•œ ํšŒ์‚ฌ๋ผ๊ณ ํ•ด์„œ ๋ฌด์กฐ๊ฑด ์ข‹์€ ์ฃผ์‹์ด๋ผ๊ณ  ๋ณผ ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค. ์ œ๊ฐ€๋ณด๊ธฐ์—๋„ ๋‹ค๋ฅธ ๊ธฐ์—…๋“ค์˜ ํ˜„์žฌ ์˜์—…์ด์ต์ด๋‚˜ ๋ฏธ๋ž˜๊ฐ€์น˜์— ๋น„ํ•ด์„œ ๊ณ ํ‰๊ฐ€๋˜์–ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค๋งŒ, ๊ทธ๋ž˜๋„ ํ…Œ์Šฌ๋ผ 100์ฃผ๋Š” ๋ณด์œ ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์•ผ ํ›„ํšŒํ•˜์ง€ ์•Š์„ ๊ฒƒ ๊ฐ™์•„์š”. ์„ค์‚ฌ ๋‹ค์‹œ 500๋‹ฌ๋Ÿฌ, ํ˜น์€ ๋” ๊นŠ์€ ๋‚˜๋ฝ์œผ๋กœ ๋–จ์–ด์ง€๋”๋ผ๋„ ๋ง์ด์ฃ . ๊ทธ๋ ‡๊ฒŒ ๋–จ์–ด์ง€๋ฉด ๋” ์‚ฌ๋ฉด ๋˜๊ตฌ์š”!
  • ์ €์˜ ํฌํŠธํด๋ฆฌ์˜ค์™€ ์œ„ ๊ณ„ํš์„ ๋ณด์‹œ๋ฉด ์•Œ๊ฒ ์ง€๋งŒ, ์ €์—๊ฒŒ ํ•ด์™ธ์ฃผ์‹์€ "ํ•ด์™ธ์ฃผ์‹=ํ…Œ์Šฌ๋ผ" ๋ผ๊ณ ํ•ด๋„ ๋ฌด๋ฐฉํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์•ž์œผ๋กœ ์„นํ„ฐ๋ณ„, ๋ฐฐ๋‹น์ฃผ๊ธฐ๋ณ„๋กœ ๋‹ค์–‘ํ•˜๊ฒŒ ๋ถ„์‚ฐํ•ด์„œ ํˆฌ์žํ•  ์ƒ๊ฐ์ด๊ณ  ๊ทธ๋Ÿฌ๊ธฐ์— ๋”์šฑ ๋ช…ํ™•ํ•œ ๋งค๋งค์›์น™ ์ˆ˜๋ฆฝํ•  ํ•„์š”๋ฅผ ๋Š๋‚๋‹ˆ๋‹ค. ์ด ๋ถ€๋ถ„์€ ์—ฌ๋Ÿฌ ์ฑ…๊ณผ ์˜์ƒ์„ ํ†ตํ•ด ๊ณ„์† ๊ณ ๋ฏผ์ค‘์ด๊ณ , ์ •๋ฆฌ๊ฐ€ ๋˜๋ฉด ๋‹ค์‹œ ์ ์–ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๋งˆ์น˜๋ฉฐ#

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

Intellij ํ”„๋กœ์ ํŠธ ๊ด€๋ฆฌ ๋‹จ์ถ•ํ‚ค

๊ฐœ์š”#

์‹ค๋ฌด์—์„œ ์ธํ…”๋ฆฌ์ œ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋‹ค๋ณด๋ฉด ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœ์ ํŠธ๋“ค์ด ์ ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ตœ๊ทผ์— ํ”„๋กœ์ ํŠธ๋ฅผ ์—ด๊ณ  ๋‹ซ๋Š”๋ฐ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค.

์ •๋ฆฌ๋˜์ง€ ์•Š์€ ์ž‘์—… ํ™˜๊ฒฝ#

์ €๋Š” ๋‹จ์ถ•ํ‚ค ์‚ฌ์šฉ์„ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค. ์ฃผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋„๊ตฌ๊ฐ€ ์žˆ๋‹ค๋ฉด, ๊ทธ๋ฆฌ๊ณ  ๊ทธ ๋„๊ตฌ์—์„œ ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Šฅ ๊ธฐ๋Šฅ์ด ์žˆ๋‹ค๋ฉด ๋‹จ์ถ•ํ‚ค๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด ์‹œ๊ฐ„์„ ํˆฌ์žํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํˆฌ์žํ•œ ์‹œ๊ฐ„์€ ์ดํ›„ ๋ฐ˜๋ณต๋˜๋Š” ์ž‘์—…์— ์†Œ์š”๋˜๋Š” ์‹œ๊ฐ„์„ ์ค„์—ฌ์ค˜์„œ ๊ธด ์‹œ๊ฐ„์œผ๋กœ ๋ดค์„ ๋•Œ ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค.

MSA ๋กœ ๊ตฌ์„ฑ๋œ ์„œ๋น„์Šค๋ฅผ ์šด์˜ํ•˜๋‹ค๋ณด๋ฉด ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ”„๋กœ์ ํŠธ๋ฅผ ์—ด์–ด์„œ ์ž‘์—…ํ•˜๊ฒŒ ๋˜๋Š”๋ฐ์š”. ์–ด๋Š์ƒˆ ์ธํ…”๋ฆฌ์ œ์ด ์ฐฝ๋งŒ 5๊ฐœ๊ฐ€ ๋„˜์–ด๊ฐ€๋ฒ„๋ ค์„œ ํšจ์œจ์ด ๋–จ์–ด์งˆ ๋•Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž‘์—…์ด ๋๋‚˜๋ฉด ๋ฐ”๋กœ๋ฐ”๋กœ ์ฐฝ์„ ๋‹ซ์•„ ์ •๋ฆฌํ•ด์•ผํ•˜๋ฉด ์ข‹์„ํ…๋ฐ ๋ง์ด์ฃ .

์‚ฌ์‹ค ์ธํ…”๋ฆฌ์ œ์ด ์ฐฝ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋ณด๊ฒ ๋‹ค๊ณ  ์—ด์–ด๋‘” ์ˆ˜๋งŽ์€ ํฌ๋กฌ์ฐฝ๊ณผ ํ„ฐ๋ฏธ๋„์ฐฝ์— ์ž‘์—… ๊ณต๊ฐ„์ด ๋ฎํ˜€๋ฒ„๋ฆฌ๊ฒŒ ๋˜๋ฉด, ์ €๋Š” ๊ถ๊ทน๊ธฐ์ธ ์žฌ์‹œ์ž‘์„ ์‹œ์ „ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ธํ…”๋ฆฌ์ œ์ด ์ฐฝ์ด ๋งŽ์ด ์—ด๋ ค์žˆ์„ ๋•Œ๋Š” ์ธํ…”๋ฆฌ์ œ์ด ๋ชจ๋“  ์ฐฝ์„ ๋‹ซ๊ณ  ๋‹ค์‹œ ํ•„์š”ํ•œ ํ”„๋กœ์ ํŠธ๋ฅผ ์—ด์–ด์„œ ์ž‘์—…์„ ๊ณ„์†ํ•ด๊ฐ”์ฃ .

๋„ˆ๋ฌด ์นœ์ ˆํ•œ ์ธํ…”๋ฆฌ์ œ์ด#

์ธํ…”๋ฆฌ์ œ์ด์—์„œ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„์ธ์ง€๋Š” ํ™•์‹คํ•˜์ง€ ์•Š์ง€๋งŒ, ์ฐฝ์ด ์—ฌ๋Ÿฌ๊ฐœ ์—ด๋ฆฐ ์ƒํƒœ๋กœ ์•ฑ์„ ์žฌ์‹œ์ž‘ํ•˜๋ฉด, ์นœ์ ˆํ•˜๊ฒŒ๋„ ์ด์ „์— ์—ด๋ ค์žˆ๋˜ ๋ชจ๋“  ์ฐฝ์„ ๋‹ค์‹œ ์—ด์–ด์ค๋‹ˆ๋‹ค. ๋‹ค์‹œ ๊น”๋”ํ•˜๊ฒŒ ์‹œ์ž‘ํ•˜๊ฒ ๋‹ค๊ณ  ์žฌ์‹œ์ž‘ํ–ˆ๋Š”๋ฐ, ํšจ๊ณผ๊ฐ€ ์—†๋Š” ์…ˆ์ด์ฃ . ๊ทธ๋ž˜์„œ ์˜ค๋žซ๋™์•ˆ ์ €๋Š” ์ธํ…”๋ฆฌ์ œ์ด ์ฐฝ์„ ํ•˜๋‚˜์”ฉ ์ฐพ์•„๊ฐ€๋ฉฐ ๋„๊ธฐ๋ฅผ ์‹œ์ „ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ตœ์†Œํ™” ํ•ด๋†“์€ ์ฐฝ๋“ค๋„ ์žˆ๊ณ , ๋งฅ ๋ฐ์Šคํฌํƒ‘ ํ™”๋ฉด ์—ฌ๊ธฐ์ €๊ธฐ ํฉ์–ด์ ธ ์žˆ์–ด์„œ ์•ฝ๊ฐ„์€ ๋ฒˆ๊ฑฐ๋กœ์šด ์ž‘์—…์ด์˜€์ง€๋งŒ, ๋‚ด๊ฐ€ ์ง‘์ค‘ํ•ด์•ผ ํ•  ์ฐฝ๋งŒ ์—ด์–ด๋†“์œผ๋ฉด ์—…๋ฌด ํšจ์œจ์ด 3~5% ์ •๋„๋Š” ํ–ฅ์ƒ๋˜๋Š” ๊ฒƒ ๊ฐ™์€ ๋Š๋‚Œ์„ ๋ฐ›์•˜์ฃ . (๊ธฐ๋ถ„ํƒ“์ด๊ฒ ์ง€๋งŒ) ๊ทธ๋ฆฌ๊ณ  ์ด๋ ‡๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋Š” ๋‹จ์ถ•ํ‚ค๋ฅผ ์ฐพ์•„๋ณด์•˜์ง€๋งŒ, ์ผ๋‹จ ์ œ ์„ ์—์„œ๋Š” ๋ชป ์ฐพ์•˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋งŒ๋Šฅ ๋‹จ์ถ•ํ‚ค CMD+SHIFT+A#

์ธํ…”๋ฆฌ์ œ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ Cmd + Shift + A ๋ฅผ ๋ชจ๋ฅด๋Š” ์‚ฌ๋žŒ์ด ์žˆ์„๊นŒ์š”? ๋งŒ์•ฝ์— ์ง€๊ธˆ๊นŒ์ง€ ๋ชฐ๋ž๋‹ค๋ฉด, ๋„ค, ์ œ๊ฐ€ ๋‹น์‹ ์˜ ๋ฏธ๋ž˜ ์‹œ๊ฐ„ ์ƒ๋‹น๋ถ€๋ถ„์„ ์ ˆ์•ฝํ•ด๋“œ๋ฆฌ๊ฒŒ ๋์Šต๋‹ˆ๋‹ค. Cmd + Shift + A ๋Š” ์ธํ…”๋ฆฌ์ œ์ด์—์„œ ์•ก์…˜ ํŒ์—…์ฐฝ์„ ์—ด์–ด์ฃผ๋Š” ๋‹จ์ถ•ํ‚ค์ž…๋‹ˆ๋‹ค. ์–ด๋–ค ์•ก์…˜์ด ์ˆ˜ํ–‰๋˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ ์ˆ˜ํ–‰ํ•  ์•ก์…˜์„ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ๋Š” ํŒ์—…์ฐฝ์„ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋‹จ์ถ•ํ‚ค์ด์ฃ .

์ž ๊ทธ๋Ÿผ ์ œ๊ฐ€ ์ด๋ฒˆ์— ์†Œ๊ฐœํ•˜๋ ค๊ณ  ํ•˜๋Š” ํ”„๋กœ์ ํŠธ ๊ด€๋ฆฌ์— ๋Œ€ํ•ด์„œ ๋งํ•ด๋ณด์ฃ . ํ•˜๋‚˜์”ฉ ์ฐฝ์„ ์ฐพ์•„์„œ ๋‹ซ๋Š”๋ฐ ์•„๋‹ˆ๋ผ Close All Projects ๋ผ๊ณ  ์ž…๋ ฅํ•˜๋ฉด ๋ชจ๋“  ํ”„๋กœ์ ํŠธ๊ฐ€ ๋‹ซํžˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์‚ฌ์‹ค ์ด ๊ธฐ๋Šฅ์€ ํ™”๋ฉด ์ƒ๋‹จ File ๋ฉ”๋‰ด์—์„œ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์–ด๋–ป๊ฒŒ ๋ณด๋ฉด ์ €๊ฑธ ์ž…๋ ฅํ•˜๋Š๋‹ˆ, ๋งˆ์šฐ์Šค์— ์†์„ ์˜ฎ๊ฒจ File โ†’ Close All Projects ๋ฅผ ๋ˆ„๋ฅด๋Š”๊ฒŒ ๋” ๋น ๋ฅผ์ˆ˜๋„ ์žˆ์ฃ . ํ•˜์ง€๋งŒ, ์ „์ฒด๋ฅผ ์ž…๋ ฅํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค๋ฉด ์ด์•ผ๊ธฐ๊ฐ€ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค.

์ € ๊ธฐ๋Šฅ์— ์•ž๊ธ€์ž์ธ CAP ๋ผ๊ณ  ์ž…๋ ฅํ•˜๋ฉด ๋ฐ”๋กœ ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ์ฃ . ๋งŒ์•ฝ ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์กฐ๊ธˆ ์•„๋ž˜ ์žˆ๋‹ค๋ฉด ์กฐ๊ธˆ ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ์ž…๋ ฅํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค. CAPro ์™€ ๊ฐ™์€ ํ˜•ํƒœ๋กœ์š”.

Monosnap 2021-09-05 16-21-49.png

์ด๋Ÿฐ ์•ž๊ธ€์ž ๊ฒ€์ƒ‰ ๋ฐฉ์‹์€ ์ธํ…”๋ฆฌ์ œ์ด ์ „๋ฐ˜์—์„œ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ํŒŒ์ผ์ด๋‚˜ ํด๋ž˜์Šค๋ฅผ ์ฐพ์„ ๋•Œ๋„ ๋™์ผํ•˜๊ฒŒ ์ฐพ์œผ๋ฉด ๋˜์ง€์š”. (์ด๋Ÿฐ ๊ฒ€์ƒ‰ ๋ฐฉ์‹์„ ์นญํ•˜๋Š”๊ฒŒ ์žˆ๋Š”๋ฐ ๊ธฐ์–ต์ด ์ž˜ ์•ˆ๋‚˜๋„ค์š”)

๋ณด๋„ˆ์Šค ์ตœ๊ทผ ํ”„๋กœ์ ํŠธ ์—ด๊ธฐ#

๋ชจ๋‘ ๋‹ซ์•˜์œผ๋ฉด ์›ํ•˜๋Š” ํ”„๋กœ์ ํŠธ๋“ค์„ ์—ด์–ด์•ผ๊ฒ ์ฃ . ๊ทธ๋ฆฌ๊ณ  ์•„๋งˆ ๋Œ€๋ถ€๋ถ„ ์—ด์–ด์•ผ ํ•˜๋Š” ํ”„๋กœ์ ํŠธ๋“ค์€ ์ตœ๊ทผ์— ์—ด์—ˆ๋˜ ํ”„๋กœ์ ํŠธ์ผ๊ฑฐ์˜ˆ์š”. ์ตœ๊ทผ ํ”„๋กœ์ ํŠธ ์—ด๊ธฐ? Open Recent Project Action ํŒ์—…์„ ์—ด์–ด์„œ ๋ญ๋ผ๊ณ  ์ž…๋ ฅํ•ด์•ผํ•˜๋Š”์ง€ ๊ฐ์ด ์˜ค์‹œ๋‚˜์š”? ORP ๋ผ๊ณ  ์ž…๋ ฅํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.!

๋งˆ์น˜๋ฉฐ#

์‚ฌ์‹ค ์ ๊ณ  ๋ณด๋ฉด ๊ฐ„๋‹จํ•œ ๊ธฐ๋Šฅ์ธ๋ฐ, ์ €๋Š” ์ƒ๋‹นํžˆ ์˜ค๋žซ๋™์•ˆ ํŠธ๋ž™ํŒจ๋“œ๋กœ ์†์„ ์˜ฎ๊ฒจ์„œ ์œ„์— ์†Œ๊ฐœํ•œ ๊ธฐ๋Šฅ๋“ค์„ ์‹คํ–‰ํ•ด์™”์Šต๋‹ˆ๋‹ค. ๊ทธ ๋™์•ˆ ๊ทธ ๋ฒˆ๊ฑฐ๋กœ์šด ๊ธฐ๋ถ„๊ณผ ์ˆ˜์—†์ด ์—ฌ๋Ÿฌ ๋ฒˆ ๋‚ญ๋น„๋œ 1~2์ดˆ๋งŒ ๋ชจ์•„๋„ ๋„ทํ”Œ๋ฆญ์Šค์—์„œ ์˜ํ™” ํ•œํŽธ์€ ๋ณผ ์ˆ˜ ์žˆ์—ˆ์„๊ฑฐ์˜ˆ์š”! (์‚ฌ์‹ค ๋„ทํ”Œ๋ฆญ์Šค๊ฐ€ ์ œ์ผ ๋‚ญ๋น„- _ใ… )

๋งŽ์€ ๋ถ„๋“ค์ด ๋ฐ”๋กœ ๊นจ๋‹ฌ์•˜๊ฒ ์ง€๋งŒ, Cmd + Shift + A ์€ ๋น„๋‹จ ํ”„๋กœ์ ํŠธ ์ „์ฒด ๋‹ซ๊ณ  ์ตœ๊ทผ ํ”„๋กœ์ ํŠธ ์—ฌ๋Š” ๊ณณ์—๋งŒ ์‚ฌ์šฉ๋˜๋Š”๊ฒŒ ์•„๋‹™๋‹ˆ๋‹ค. ๋ง๊ทธ๋Œ€๋กœ ์ธํ…”๋ฆฌ์ œ์ด ๋‚ด ๋ชจ๋“  ์•ก์…˜๋“ค์„ ๊ฒ€์ƒ‰ํ•˜๊ณ  ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์ฃ . ๋ฌด์–ธ๊ฐ€๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ํด๋ฆญํ•ด์„œ ์‹คํ–‰ํ•˜๊ณ  ์žˆ๋‚˜์š”? Cmd + Shift + A ๋ฅผ ๋ˆŒ๋Ÿฌ์„œ ๊ฒ€์ƒ‰ํ•ด๋ณด์„ธ์š”! ๋‹น์‹ ์˜ ์†Œ์ค‘ํ•œ 1์ดˆ๋ฅผ ์ง€์ผœ์ค„๊ฑฐ์˜ˆ์š”.

Spring Rest Docs & OAS - ์‹œ์ž‘ํ•˜๊ธฐ

๊ฐœ์š”#

์ง€๋‚œ ๊ธ€ Spring Rest Docs & OAS ์˜ ํ•„์š”์„ฑ ์—์„œ ์ด ๋‘˜์˜ ์กฐํ•ฉ์ด ์™œ ํ•„์š”ํ•œ์ง€ ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์ด์ œ ๊ฐ„๋‹จํ•œ ์ƒ˜ํ”Œ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด OAS ๋ฅผ ์‚ฌ์šฉํ•ด์„œ API ๋ฌธ์„œ๋ฅผ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ณธ๋ฌธ์— ๋“ฑ์žฅํ•˜๋Š” ์ฝ”๋“œ๋Š” ๊นƒํ—ˆ๋ธŒ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์‹œ์ž‘ํ•˜๊ธฐ ์ „์—#

์ด ํŠœํ† ๋ฆฌ์–ผ์€ restdocs-api-spec ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ์— ์ค‘์ ์„ ๋‘๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์•„๋ž˜ ๋‚˜์—ด๋œ ๋ฐฉ๋ฒ•๋“ค์€ ์ƒ์„ธํžˆ ์„ค๋ช…ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  • Sprint Rest Docs ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•
  • Spring Boot Start Web ์œผ๋กœ API ๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•

restdocs-api-spec ํ”„๋กœ์ ํŠธ๋Š” ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๊ตฌ์„ฑ ์š”์†Œ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์œผ๋ฉฐ, mockmvc ๋ฅผ ์‚ฌ์šฉํ•œ ํ…Œ์ŠคํŠธ์™€ restassured ์„ ์‚ฌ์šฉํ•œ ํ…Œ์ŠคํŠธ ๋‘˜ ๋‹ค ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ๋‘ ํ…Œ์ŠคํŠธ์˜ ํฐ ์ฐจ์ด์ ์€ MockMvc ๋Š” @WebMvcTest ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , Rest Assured ๋Š” @SpringBootTest ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ์ ์ธ๋ฐ ์ž์„ธํ•œ ๋‚ด์šฉ์€ MockMvc VS RestAssured ๊ธ€์„ ์ฐธ๊ณ ๋˜์ง€๋งŒ, ์ด ๊ธ€์ด ์ž‘์„ฑ๋œ ์‹œ์ ์€ 2020๋…„ 8์›”๋กœ 1๋…„์ด ์ง€๋‚œ ํ˜„์žฌ๋Š” io.rest-assured:spring-mock-mvc module ์ด ์กด์žฌํ•˜์—ฌ RestAssured ๋ฅผ ์‚ฌ์šฉํ•˜๋”๋ผ๋„ ์ „์ฒด Bean ์„ ๋กœ๋“œํ•  ํ•„์š”๊ฐ€ ์—†์–ด์กŒ์Šต๋‹ˆ๋‹ค.

ํ…Œ์ŠคํŠธ ๊ฐ€๋…์„ฑ์ด๋‚˜, ์ž‘์„ฑ์˜ ํŽธ๋ฆฌํ•จ์„ ๋ณด์•˜์„ ๋•Œ RestAssured ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ์ข‹์•„๋ณด์ด๋‚˜, ์ด์ „์— ์‚ฌ์šฉ ๊ฒฝํ—˜์ด ์—†์–ด์„œ, ์ด ๊ธ€์—์„œ๋Š” ์ต์ˆ™ํ•œ MockMvc ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ถ”ํ›„ RestAssured ๋ฅผ ์‚ฌ์šฉํ•œ ์ƒ˜ํ”Œ๋„ ์ž‘์„ฑํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ฐ”๋กœ RestAssured ๋กœ ์‹œ๋„ํ•ด๋ณด๊ณ  ์‹ถ์€ ๋ถ„๋“ค์€ ์•„๋ž˜ ๊ธ€๋“ค์„ ์ฐธ๊ณ ํ•˜๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๊ฐ„๋‹จํ•œ ์ƒ˜ํ”Œ API ๊ตฌํ˜„#

๋จผ์ € ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์กฐํšŒํ•˜๋Š” ๊ฐ„๋‹จํ•œ API ๋ฅผ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜๋“ค ์„ค์ •์„ ํ•ด์ฃผ๊ณ ...

plugins {
id 'org.springframework.boot' version '2.5.4'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
id 'com.epages.restdocs-api-spec' version '0.11.5' // (1)
}
group = 'net.dezang'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' // (2)
testImplementation 'com.epages:restdocs-api-spec-mockmvc:0.11.5' // (2) For openapi spec
}
openapi3 { // (3)
server = 'http://localhost:8080'
title = 'USER-API'
description = '์‚ฌ์šฉ์ž ๋ฆฌ์†Œ์Šค API ์ž…๋‹ˆ๋‹ค.'
version = '0.1.0'
format = 'yaml'
}
test {
useJUnitPlatform()
}
  • (1) restdocs-api-spec ํ”Œ๋Ÿฌ๊ทธ์ธ ์ถ”๊ฐ€
  • (2) spring-restdocs-mockmvc , restdocs-api-spec-mockmvc ์˜์กด์„ฑ ์ถ”๊ฐ€
  • (3) openapi3 ์— ์„ค์ • ์ •๋ณด ์ž…๋ ฅ

์œ ์ € ์ •๋ณด๋ฅผ ์กฐํšŒํ•˜๋Š” ๊ฐ„๋‹จํ•œ API ๋ฅผ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค.

package net.dezang.restdocopenapi;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class RestdocOpenapiApplication {
public static void main(String[] args) {
SpringApplication.run(RestdocOpenapiApplication.class, args);
}
}
package net.dezang.restdocopenapi;
import lombok.Builder;
import lombok.Getter;
@Getter
@Builder
class User {
private Long id;
private String username;
private String password;
private Integer age;
private boolean enabled;
}
package net.dezang.restdocopenapi;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.stream.Collectors;
@RestController
@RequestMapping("users")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@GetMapping
public ResponseEntity<List<UserDto.Response>> list() {
List<UserDto.Response> responses = userService.list().stream()
.map(UserDto.Response::of)
.collect(Collectors.toList());
return ResponseEntity.ok(responses);
}
@NoArgsConstructor(access = AccessLevel.PRIVATE)
static class UserDto {
@Data
@AllArgsConstructor
static class Response {
private String username;
private Integer age;
public static Response of(User domain) {
return new Response(domain.getUsername(), domain.getAge());
}
}
}
}
package net.dezang.restdocopenapi;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
@Service
class UserService {
public List<User> list() {
return Collections.singletonList(User.builder()
.id(1L)
.username("dezang")
.password("!topSecret!")
.age(20)
.enabled(true)
.build());
}
}

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

OPENAPI SPEC ๋ฌธ์„œ ์ƒ์„ฑ#

package net.dezang.restdocopenapi;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import java.util.Collections;
import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document; // (1)
import static org.mockito.BDDMockito.given;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@AutoConfigureRestDocs
@WebMvcTest(UserController.class)
class UserApiDoc {
@Autowired
MockMvc mockMvc;
@MockBean
UserService userService;
@Test
void list() {
//given
given(userService.list())
.willReturn(Collections.singletonList(
User.builder()
.username("dezang")
.age(10)
.build()
));
//when
ResultActions resultActions = mockMvc.perform(get("/users"));
//then
resultActions
.andExpect(status().isOk())
.andDo(document("list-user",
responseFields(
fieldWithPath("[].username").description("์‚ฌ์šฉ์ž ์•„์ด๋””"),
fieldWithPath("[].age").description("์‚ฌ์šฉ์ž ๋‚˜์ด")
)))
.andDo(print());
}
}
  • (1): MockMvcRestDocumentation ์ด ์•„๋‹Œ MockMvcRestDocumentationWrapper ๋‚ด document ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑ

์ฝ”๋“œ ์ž‘์„ฑ์€ ๋๋‚ฌ์Šต๋‹ˆ๋‹ค. ์ด์ œ openapi3 ๋ฌธ์„œ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ์ œ๊ณตํ•˜๋Š” ํ…Œ์Šคํฌ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

./gradlew openapi3

์œ„ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋ฉด, ํ…Œ์ŠคํŠธ๊ฐ€ ๋Œ๊ณ  ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ๋ฌผ์ด build ๊ฒฝ๋กœ์— ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

build
โ”œโ”€โ”€ api-spec
โ”‚ย ย  โ””โ”€โ”€ openapi3.yaml
...
โ”œโ”€โ”€ generated-snippets
โ”‚ย ย  โ””โ”€โ”€ list-user
โ”‚ย ย  โ”œโ”€โ”€ curl-request.adoc
โ”‚ย ย  โ”œโ”€โ”€ http-request.adoc
โ”‚ย ย  โ”œโ”€โ”€ http-response.adoc
โ”‚ย ย  โ”œโ”€โ”€ httpie-request.adoc
โ”‚ย ย  โ”œโ”€โ”€ request-body.adoc
โ”‚ย ย  โ”œโ”€โ”€ resource.json
โ”‚ย ย  โ”œโ”€โ”€ response-body.adoc
โ”‚ย ย  โ””โ”€โ”€ response-fields.adoc
...

์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ํŒŒ์ผ์ด ์ €๊ธฐ ๋ณด์ด๋„ค์š”. build/api-spec/openapi3.yaml ์ž…๋‹ˆ๋‹ค. ์•„์›ƒํ’‹ ๊ฒฝ๋กœ๋Š” ์ฒ˜์Œ ๊ณต์œ ํ•œ build.gradle ์— openapi3 ์—์„œ ์„ค์ • ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ yaml ํŒŒ์ผ์„ ํ•œ๋ฒˆ ์‚ดํŽด๋ณผ๊นŒ์š”?

openapi: 3.0.1
info:
title: USER-API
description: ์‚ฌ์šฉ์ž ๋ฆฌ์†Œ์Šค API ์ž…๋‹ˆ๋‹ค.
version: 0.1.0
servers:
- url: http://localhost:8080
tags: []
paths:
/users:
get:
tags:
- users
operationId: list-user
responses:
"200":
description: "200"
content:
application/json:
schema:
$ref: '#/components/schemas/users450998075'
examples:
list-user:
value: "[{\"username\":\"dezang\",\"age\":10}]"
components:
schemas:
users450998075:
type: array
items:
type: object
properties:
age:
type: number
description: ์‚ฌ์šฉ์ž ๋‚˜์ด
username:
type: string
description: ์‚ฌ์šฉ์ž ์•„์ด๋””

์ƒ๊ฐ๋ณด๋‹ค ๋ณ„๊ฑฐ ์—†์–ด๋ณด์ด์ง€๋งŒ, ์ŠคํŽ™ ์ž์ฒด๋Š” ๊ฐ•๋ ฅํ•ฉ๋‹ˆ๋‹ค. ์ด์ „ ๊ธ€ Spring Rest Docs & OAS ์˜ ํ•„์š”์„ฑ ์— ๋Œ€ํ•œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ŠคํŽ™ ๋ฌธ์„œ ํ™œ์šฉํ•˜๊ธฐ#

์ด์ œ ์œ ์—ฐํ•œ ๊ฒฐ๊ณผ๋ฌผ์„ ์–ป์—ˆ์œผ๋‹ˆ, OAS ๋ฅผ ์ง€์›ํ•˜๋Š” ๋„๊ตฌ๋‚˜ ์„œ๋น„์Šค๋ฅผ ํ™œ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ผ๋‹จ ์—ฌ๊ธฐ์„œ๋Š” ๋„์ปค๋ฅผ ํ™œ์šฉํ•˜์—ฌ Swagger ๋ฅผ ์‚ฌ์šฉํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

docker run --rm -p 80:8080 \
-v __YOUR_BUILD_PATH__/api-spec:/usr/share/nginx/html/docs/ \
-e URL=docs/openapi3.yaml \
swaggerapi/swagger-ui

๋“œ๋””์–ด API ๋ฌธ์„œ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!

Swagger UI 2021-09-05 13-56-49.png

๋งˆ์น˜๋ฉฐ#

์ด์ œ API ๋ฌธ์„œ๋ฅผ ๋งŒ๋“ค์—ˆ์œผ๋‹ˆ ๋์ผ๊นŒ์š”? REST DOCS + OAS ๋ฅผ ์‹œ์ž‘ํ•˜๊ฒŒ ๋œ ์ด์œ ๊ฐ€ MSA ๊ตฌ์กฐ์—์„œ ๋ถ„์‚ฐ๋˜์–ด์žˆ๋Š” API ๋ฌธ์„œ๋ฅผ ์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ํ†ตํ•ฉํ•ด์„œ ๋ณผ ์ˆ˜ ์žˆ์„๊นŒ? ์˜€๋˜ ๊ฒƒ์„ ๊ธฐ์–ตํ•˜์‹œ๋‚˜์š”? ๊ฐ ์„œ๋น„์Šค๊ฐ€ ์–ด๋–ค ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•ด์„œ OAS ๋ผ๋Š” ์ŠคํŽ™์„ ์ง€ํ‚จ ๋ฌธ์„œ๋ฅผ ์ƒ์„ฑํ–ˆ๋‹ค๋ฉด, ์ด ๋ฌธ์„œ๋ฅผ ์–ด๋–ป๊ฒŒ ์„œ๋น™ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์„๊นŒ์š”? ๋‹ค์Œ ๊ธ€์—์„œ๋Š” ์—ญ์‹œ ๋ถ„์‚ฐ๋˜์–ด ์žˆ๋Š” OAS ํŒŒ์ผ์„ ์–ด๋–ป๊ฒŒ ์ž๋™์œผ๋กœ ํ•œ ๊ณณ์œผ๋กœ ๋ชจ์œผ๊ณ , ์‚ฌ์šฉ์ž๋“ค์—๊ฒŒ ๋ณด์—ฌ์ค„ ๊ฒƒ์ธ์ง€ ๊ณ ๋ฏผ์˜ ๊ฒฐ๊ณผ๋ฅผ ๊ณต์œ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

Spring Rest Docs & OAS ์˜ ํ•„์š”์„ฑ

๊ฐœ์š”#

ํ…Œ์ŠคํŠธ๋ฅผ ํ†ตํ•ด API ๋ฌธ์„œ๊ฐ€ ์ฝ”๋“œ์™€ ์ผ์น˜๋จ์„ ๋ณด์žฅํ•ด์ฃผ๋Š” SPRING REST DOCS ๊ณผ ๋›ฐ์–ด๋‚œ ๋ฒ”์šฉ์„ฑ์„ ์ž๋ž‘ํ•˜๋Š” OPEN API SPEC (OAS 3) ์˜ ์กฐํ•ฉ์œผ๋กœ ๊ฐœ๋ฐœ๋œ API ํ™œ์šฉ๋„๋ฅผ ๊ทน๋Œ€ํ™” ์‹œํ‚ค๋Š” ๋ฒ•์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  API ๋ฌธ์„œ๋ฅผ ํ•œ ๊ณณ์œผ๋กœ ๋ชจ์„ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ๋ณด๋„ˆ์Šค์ž…๋‹ˆ๋‹ค.

SPRING REST DOCS ๊ณผ OAS ์กฐํ•ฉ์ด ํ•„์š”ํ•œ ์ด์œ #

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

๊ณ„์†ํ•ด์„œ ๋Š˜์–ด๋‚˜๋Š” API ์„œ๋ฒ„์™€ ๋ถ„์‚ฐ๋˜๋Š” API ๋ฌธ์„œ#

์„œ๋น„์Šค๊ฐ€ ํ™•์žฅํ•จ์— ๋”ฐ๋ผ API ์—”๋“œํฌ์ธํŠธ๊ฐ€ ๋Š˜์–ด๋‚˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€ํ”ผํ–ˆ๊ณ , MSA ํ™˜๊ฒฝ์—์„œ ๊ฐœ๋ฐœ๋˜๊ณ  ์žˆ๋Š” ์ œํ’ˆ์ธ์ง€๋ผ, API ์ถ”๊ฐ€๋Š” API ์„œ๋ฒ„์˜ ์ถ”๊ฐ€๋กœ ์ด์–ด์กŒ์Šต๋‹ˆ๋‹ค. ๊ฐ ์„œ๋ฒ„๋งˆ๋‹ค REST DOCS ์„ ํ†ตํ•ด ๋งŒ๋“ค์–ด์ง€๋Š” API ๋ฌธ์„œ๋Š” ๊ฐ ์„œ๋ฒ„์˜ ํŠน์ • ์—”๋“œํฌ์ธํŠธ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์—ˆ๊ณ , ์šฐ๋ฆฌ ํŒ€์€ ์—ฌ๊ธฐ์ €๊ธฐ ํฉ์–ด์ ธ์žˆ๋Š” API ๋ฌธ์„œ๋ฅผ ์ฐพ์•„๋‹ค๋‹ˆ๋ฉฐ ๊ฐœ๋ฐœ์„ ํ•ด์•ผํ•˜๋Š”๋ถˆํŽธํ•จ์„ ๊ฒช์–ด์•ผํ–ˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ์ž๋ฐ”๊ฐ€ ์•„๋‹ˆ๋ผ, ๋‹ค๋ฅธ ์–ธ์–ด๋กœ ๊ฐœ๋ฐœ๋œ API์˜ ๊ฒฝ์šฐ REST DOCS ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์—†์—ˆ๊ณ , ์ด๋Ÿฐ ์ด์œ ๋กœ REST DOCS ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•˜๋Š” API ์„œ๋ฒ„๋Š” ์‚ฌ๋‚ด Notion ์— API ๋ฌธ์„œ๋ฅผ ์ž‘์„ฑํ•ด ๊ณต์œ ํ•˜๋„๋ก ํ•˜์˜€์œผ๋‚˜, ์—ญ์‹œ๋‚˜ ํฌ๊ณ  ์ž‘์€ ์ˆ˜์ • ์‚ฌํ•ญ๋“ค์ด ๋นˆ๋ฒˆํ•˜๊ฒŒ ๋™๊ธฐํ™”๋˜์ง€ ์•Š์•˜๊ณ , ๋…ธ์…˜์— ์žˆ๋Š” API ๋ฌธ์„œ๋Š” ์‹ ๋ขฐ๋ฅผ ์žƒ์–ด๊ฐ€๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ์‚ฌ๋‚ด์— ์žˆ๋Š” ๋ชจ๋“  API ๋ฅผ ํ•œ ๊ณณ์—์„œ ๋ณผ ์ˆ˜ ์žˆ์„๊นŒ?#

์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ์—ฌ๊ธฐ ์ €๊ธฐ ํฉ์–ด์ ธ์žˆ๋Š” API ๋ฅผ ํ•œ ๊ณณ์—์„œ ๋ณผ ์ˆ˜ ์žˆ์„๊นŒ์š”? ๊ทธ๋ž˜์„œ ์‚ฌ๋‚ด์— ์žˆ๋Š” ๋ชจ๋“  ๊ธฐ๋Šฅ๊ณผ ๋ฆฌ์†Œ์Šค๋ฅผ ์ตœ๋Œ€ํ•œ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํ™˜๊ฒฝ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์„๊นŒ์š”? ์ฒ˜์Œ์—๋Š” ๊ฐ ์„œ๋ฒ„์— ์žˆ๋Š” SPRING REST DOCS ์œผ๋กœ ์ƒ์„ฑ๋œ html ๋ฌธ์„œ๋ฅผ ๋ชจ์•„์„œ ํ•œ ์›น ์„œ๋ฒ„์—์„œ ํ˜ธ์ŠคํŒ…์„ ๊ณ ๋ คํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค๋งŒ, ๊ทธ ๊ฐ๊ฐ์˜ ๋ฌธ์„œ ๋งํฌ๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” ๋ณ„๋„ ํŽ˜์ด์ง€๊ฐ€ ํ•„์š”ํ–ˆ๊ณ , ๊ทธ ๊ณณ์—๋Š” Notion ๋งํฌ๋„ ๋“ค์–ด๊ฐ€์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ด€๋ฆฌ๊ฐ€ ์ž˜ ๋  ์ˆ˜ ์žˆ์„๊นŒ์š”? ๋ชจ๋“  API ์„œ๋ฒ„๊ฐ€ ์ฝ”๋“œ๋ฅผ ๊ธฐ๋ฐ˜ํ•˜์—ฌ ๊ฐ™์€ ํ˜•ํƒœ(์ธํ„ฐํŽ˜์ด์Šค)๋กœ API ์ŠคํŽ™์„ ์ •์˜ํ•œ ๊ฒฐ๊ณผ๋ฌผ์„ ๋งŒ๋“ค์–ด ๋‚ผ ์ˆ˜๋Š” ์—†์„๊นŒ์š”?

์ด ์‹œ์ ์—์„œ REST DOCS ์„ ์ž ๊น ํฌ๊ธฐํ•˜๊ณ  ๋‹ค๋ฅธ ๋Œ€์•ˆ์„ ์ฐพ์•„๋ณด๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. API ๋ธ”๋ฃจํ”„๋ฆฐํŠธ, ์Šค์›จ๊ฑฐ ๊ณผ ๊ฐ™์€ ์˜คํ”„์†Œ์Šค๋ถ€ํ„ฐ, ์ตœ๊ทผ ์ž์ฃผ ๋ณด์ด๋Š” ๋ฆฌ๋“œ๋ฏธ๋‹ท์ปด, Stoplight ์œ ๋ฃŒ ์†”๋ฃจ์…˜๋„ ๊ฒ€ํ† ํ•ด๋ณด์•˜์ฃ . ์œ ๋ฃŒ ์†”๋ฃจ์…˜์„ ์•Œ์•„๋ณด๋‹ˆ ์ •์˜๋œ API ๋ฅผ ๋ฏธ๋ คํ•œ ์‚ฌ์ดํŠธ๋กœ ํ˜ธ์ŠคํŒ…ํ•ด์ฃผ๋Š” ์—ญํ• ์„ ์ฃผ๋กœํ•˜๊ณ  API Spec ์ž์ฒด๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ๋งŒ๋“ค์–ด์„œ ๋„ฃ์–ด์•ผํ–ˆ์Šต๋‹ˆ๋‹ค. (์–ด์ฐŒ๋ณด๋ฉด ๋‹น์—ฐํ•œ ์ด์•ผ๊ธฐ...) ๊ทธ๋Ÿฐ๋ฐ ๋ฌธ์„œ๋ฅผ ์ฝ๋‹ค๋ณด๋‹ˆ OAS 3, Swagger Support ๋ผ๋Š” ๋ฌธ๊ตฌ๊ฐ€ ์—ฌ๊ธฐ์ €๊ธฐ์„œ ๋ณด์ด๋”๊ตฐ์š”. Swagger๋Š” ์‚ฌ์šฉํ•ด๋ดค๊ณ , OAS 3 ๋Š” Open Api Specification v3 ์˜ ์ถ•์•ฝ์–ด์˜€์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์„œ ํ•ด๊ฒฐ๋ฐฉ๋ฒ•์ด ์–ด๋ ดํ’‹ ๋ณด์ด๋Š” ๊ฒƒ ๊ฐ™์•˜์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜, ๊ด€๊ฑด์€ API Specification.#

์œ„์—์„œ ์–ธ๊ธ‰ํ•œ '๋ชจ๋“  API ์„œ๋ฒ„๊ฐ€ ์ฝ”๋“œ๋ฅผ ๊ธฐ๋ฐ˜ํ•˜์—ฌ ๊ฐ™์€ ํ˜•ํƒœ(์ธํ„ฐํŽ˜์ด์Šค)๋กœ API ์ŠคํŽ™์„ ์ •์˜ํ•œ ๊ฒฐ๊ณผ๋ฌผ์„ ๋งŒ๋“ค์–ด ๋‚ผ ์ˆ˜๋Š” ์—†์„๊นŒ์š”?' ์€ ์ €๋งŒ ๊ณ ๋ฏผํ–ˆ๋˜ ๊ฒƒ์€ ์•„๋‹ˆ์˜€์Šต๋‹ˆ๋‹ค. ์ด๋ฏธ ์˜›๋‚ ๋ถ€ํ„ฐ ์„ ๋ฐฐ๋“ค์ด ๊ณ ๋ฏผํ•ด์™”๊ณ , ๊ทธ์— ๋Œ€ํ•œ ์ •์˜๋„ ๋งŒ๋“ค์–ด ๋†“์•˜์Šต๋‹ˆ๋‹ค.

OpenAPI v3.0 was released in July, 2017, by the OpenAPI Initiative, a consortium of member companies who want to standardize how REST APIs are described. There are various other approaches to API description

OpenAPI v3.0์€ REST API ์„ค๋ช… ๋ฐฉ์‹์„ ํ‘œ์ค€ํ™”ํ•˜๋ ค๋Š” ํšŒ์›์‚ฌ ์ปจ์†Œ์‹œ์—„์ธ OpenAPI Initiative์—์„œ 2017๋…„ 7์›”์— ์ถœ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค. API ์„ค๋ช…์— ๋Œ€ํ•œ ๋‹ค์–‘ํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์ด ์žˆ์Šต๋‹ˆ๋‹ค.

Stoplight - How to choose your api specification

์—ฌ๊ธฐ์„œ ์†Œ๊ฐœํ•˜๋Š” ์ ‘๊ทผ ๋ฐฉ์‹์€ OpenAPI, JSON Schema, API Blueprint, RAML ์ด๋ฉฐ, ์ถ”์ฒœํ•˜๋Š” ๋…€์„์€ OpenAPI v3 ์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ ์ €๊ธฐ์„œ ๋ดค๋˜ OAS3 ๋ฐ”๋กœ ๊ทธ ๋…€์„์ด์ฃ . OAS3 ์— ๋Œ€ํ•ด์„œ ์ž์„ธํžˆ ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด ์—ฌ๊ธฐ ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด์ œ ๊ฐ API ์„œ๋ฒ„๊ฐ€ ์–ด๋–ค ํ˜•์‹์œผ๋กœ ํ‘œ์ค€ํ™”๋œ ๊ฒฐ๊ณผ๋ฌผ์„ ์ƒ์‚ฐํ•ด์•ผํ•˜๋Š”์ง€๋Š” ๊ฒฐ์ •๋˜์—ˆ์Šต๋‹ˆ๋‹ค. OAS ์ŠคํŽ™์— ๋งž๋Š” ํ˜•ํƒœ๋กœ yaml ๋˜๋Š” json ํŒŒ์ผ์„ ๋–จ๊ถˆ์ฃผ๋ฉด, ๊ทธ ํŒŒ์ผ์„ ์ด์˜๊ฒŒ ๋ณด์—ฌ์ค„ ๋„๊ตฌ์™€ ์„œ๋น„์Šค๋Š” ๋„๋ ค์žˆ์Šต๋‹ˆ๋‹ค. ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ OSA3 ๋Š” ๊ธฐ๊ณ„, ๋„๊ตฌ๊ฐ€ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋˜์—ˆ๋‹ค๊ณ  ํ•˜๋‹ˆ, ์ผ๋‹จ OAS ์ŠคํŽ™ ํŒŒ์ผ๋งŒ ์žˆ์œผ๋ฉด ๋ญ๋“ ์ง€ ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋„ค์š”. ์ž ๊ทธ๋Ÿผ ์–ด๋–ป๊ฒŒ ์ด ํŒŒ์ผ์„ API ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ์–ป์„ ์ˆ˜ ์žˆ์„๊นŒ์š”? ์‚ฌ๋žŒ์ด ํ•˜๋‚˜ํ•˜๋‚˜ ์ž‘์„ฑํ•  ํ˜•ํƒœ๋Š” ์•„๋‹Œ๋ฐ ๋ง์ด์ฃ .

์Šค์›จ๊ฑฐ๋ฅผ ๋‹ค์‹œ ์จ์•ผ ํ• ๊นŒ?#

OAS ๋Š” API ์ŠคํŽ™์„ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฐ€์žฅ ๋Œ€ํ‘œ์ ์ธ ํฌ๋งท์ด๋ผ ๊ฐ์ข… ์–ธ์–ด์—์„œ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ํ”„๋กœ์ ํŠธ๋“ค์ด ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” ๋Œ€ํ‘œ์ ์œผ๋กœ Spring ์ชฝ์— SpringDoc Project ์™€ Nodejs ์ชฝ์—๋Š” Swagger-jsdoc ์ด๋ผ๋Š” ํ”„๋กœ์ ํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ๋‚˜ ์Šค์›จ๊ฑฐ๋Š” OAS ์ ๊ทน ์ง€์›ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, ์ด์ „๋ถ€ํ„ฐ ์ž๋ฐ”/์Šคํ”„๋ง ์ง„์˜์—์„œ๋„ ๋งŽ์ด ์“ฐ์ด๋Š” ํ”„๋กœ์ ํŠธ ์ž…๋‹ˆ๋‹ค. ์–ด์ฐŒ๋ณด๋ฉด SPRINT REST DOC ๋ณด๋‹ค ๋” ๋งŽ์ด ์“ฐ์ด๋Š” ๋…€์„์ผ์ง€๋„ ๋ชจ๋ฅด๊ฒ ๋„ค์š”. ์Šคํ”„๋ง์—์„œ ์–ด๋…ธํ…Œ์ด์…˜ ๋ช‡ ๊ฐœ๋กœ ๊ธฐ๋ณธ์ ์ธ ๋ฌธ์„œ๋ฅผ ๋š๋”ฑ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๋„๊ตฌ๋‹ˆ๊นŒ์š”. ๋‹ค๋งŒ ์˜ˆ์ „์— ์Šค์›จ๊ฑฐ๋ฅผ ์จ ๋ณธ ์ž…์žฅ์—์„œ ์ปจํŠธ๋กค๋Ÿฌ ์ฝ”๋“œ์— API ์„ค๋ช…๋ฅผ ์œ„ํ•œ ์ฝ”๋“œ๊ฐ€ ๋„ˆ๋ฌด ๋•์ง€๋•์ง€ ๋ถ™์–ด์žˆ์–ด์„œ ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์ง€๋Š” ๋‹จ์ ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ œํ’ˆ ์ฝ”๋“œ์™€ ๋™๊ธฐํ™”๋„ ๋ณด์žฅํ•˜์ง€ ์•Š๊ตฌ์š”.

Rest Docs ์ด Open API Spec ์„ ๋–จ๊ถˆ์ค„ ์ˆ˜๋งŒ ์žˆ๋‹ค๋ฉด.#

REST DOCS ์‚ฌ์šฉ์„ ํฌ๊ธฐํ•˜๊ณ  ์—ฌ๊ธฐ๊นŒ์ง€ ์™”์ง€๋งŒ, ๋‹ค์‹œ๊ธˆ REST DOCS ์ด ๊ทธ๋ฆฌ์›Œ์ง€๋Š” ์ˆœ๊ฐ„์ž…๋‹ˆ๋‹ค. REST DOCS ์ด ์™„์„ฑ๋œ HTML ๋ฌธ์„œ๋ฅผ ์ตœ์ข… ๊ฒฐ๊ณผ๋ฌผ๋กœ ์ƒ์„ฑํ•˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ, OPEN API Spec ์œผ๋กœ ์ƒ์„ฑํ•  ์ˆ˜๋งŒ ์žˆ๋‹ค๋ฉด, ๋งŽ์€ ๊ฒƒ๋“ค์ด ํ•ด๊ฒฐ๋ ํ…๋ฐ ๋ง์ด์ฃ . ๊ทธ๋Ÿฐ๋ฐ! ๊ทธ๋ ‡๊ฒŒ ๋ช…ํ™•ํ•œ ๋ฐฉํ–ฅ์„ ์žก๊ณ  ๊ตฌ๊ธ€๋ง์„ ํ•˜๋‹ˆ, ์ €์™€ ๊ฐ™์€ ๊ณ ๋ฏผ ๋์— ๊ทธ ํ•ด๋‹ต์„ ์–ป์–ด ๋‚ธ ๋ถ„ ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์—ฌ๊ธฐ์„œ ๋ฐœ๊ฒฌํ•œ ์ด ๋ชจ๋“  ๊ฒƒ์„ ํ•ด๊ฒฐํ•ด์ฃผ๋Š” restdocs-api-spec ํ”„๋กœ์ ํŠธ! ๊ธฐ์กด ํด๋ž˜์Šค๋“ค์„ ๋žฉํ•‘ํ•ด์„œ ๋งŒ๋“ค์–ด๋†”์„œ Import ๋งŒ ๋ฐ”๊ฟ”์ค˜๋„ ๊ธฐ์กด ์ฝ”๋“œ์— ํฐ ๋ณ€ํ™”์—†์ด ์ ์šฉ์ด ๊ฐ€๋Šฅํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด์„œ REST DOCS ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค๋ฉด, OPENAPI 3 ์ŠคํŽ™์œผ๋กœ ํŒŒ์ผ์ด ๋š ๋–จ์–ด์ง‘๋‹ˆ๋‹ค. ์œ ๋ ˆ์นด!

๋งˆ์น˜๋ฉฐ#

๋ถ„์‚ฐ๋œ API ๋ฌธ์„œ๋“ค, ์ด ๋ฌธ์„œ๋ฅผ ํ•œ ๊ณณ์œผ๋กœ ๋ชจ์œผ๊ณ ์ž ํ–ˆ๋˜ ๊ฐˆ๋ง(?) ๊ณผ OAS ์™€restdocs-api-spec ์ด๋ผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋งŒ๋‚˜๊ฒŒ ๋˜๊ธฐ๊นŒ์ง€์— ์—ฌ์ •์„ ์†Œ๊ฐœํ•ด๋“œ๋ ธ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ๊ธ€์—์„œ๋Š” ๋ณธ๊ฒฉ์ ์œผ๋กœ restdoc-api-spec ์„ ์‚ฌ์šฉํ•ด์„œ OAS ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ณ , ์Šค์›จ๊ฑฐ์—์„œ ํŒŒ์ผ์„ ๋ณด๊ธฐ ์ข‹์€ ํ˜•ํƒœ๋กœ ์„œ๋น™ํ•˜๋Š” ๋ถ€๋ถ„์„ ์ ์–ด๋ณผ๊ป˜์š”. ๊ธด ๊ธ€ ์ฝ์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

Go ์‹œ์ž‘ํ•˜๊ธฐ - 01

๋“ค์–ด๊ฐ€๋ฉฐ#

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

๋ชจ๋“  ๊ณผ์ •์— ๋Œ€ํ•œ ์ฝ”๋“œ๋Š” GitHub ์— ๊ณต๊ฐœ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ„๋‹จํ•˜๊ฒŒ ์‹œ์ž‘ํ•˜๊ธฐ#

๊ฐœ๋ฐœ ํ™˜๊ฒฝ ๊ตฌ์„ฑ#

๋จผ์ € Go๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด Go ๋ฅผ ์„ค์น˜ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์„ค์น˜๋Š” ๋„ˆ๋ฌด๋‚˜ ๊ฐ„๋‹จํ•ด์„œ ์—ฌ๊ธฐ์—์„œ๋Š” ๋”ฐ๋กœ ๋‹ค๋ฃจ์ง€ ์•Š๊ฒ ์Šต๋‹ˆ๋‹ค.

์ด์ œ ์–ด๋–ค ์—๋””ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ฝ”๋”ฉ์„ ํ• ์ง€ ๊ฒฐ์ •ํ•ด์•ผํ•˜๋Š”๋ฐ์š”. ์ €๋Š” ์ธํ…”๋ฆฌ์ œ์ด์˜ ๋…ธ์˜ˆ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ธํ…”๋ฆฌ์ œ์ด๋ฅผ ์‚ฌ์šฉํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ๋Š” Go ๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋ฐ, ํ”Œ๋Ÿฌ๊ทธ์ธ๋งŒ ์„ค์น˜ํ•˜๋ฉด GoLand (JetBrain ์˜ Go ์ „์šฉ IDE) ์˜ ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•˜๋‹ˆ ํ™˜ํ˜ธ์„ฑ์„ ์ง€๋ฅด๋ฉฐ ์–ด์„œ ์„ค์น˜ํ•ด์ค๋‹ˆ๋‹ค.

Preferences 2021-08-15 17-13-09.png

์„ค์น˜๊ฐ€ ๋˜์—ˆ์œผ๋ฉด, ๋นจ๋ฆฌ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ฃ . ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ์ˆœ๊ฐ„๋ถ€ํ„ฐ ๊ทธ ํ”„๋กœ์ ํŠธ์˜ ์—ญ์‚ฌ๋Š” ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ ์—ญ์‚ฌ๋Š” commit ์œผ๋กœ ๊ธฐ๋ก๋˜์ฃ . ์ขŒ์ธก์—์„œ Go ๋ฅผ ์„ ํƒํ•˜๊ณ  ๋‹ค์Œ์„ ๋ˆŒ๋Ÿฌ ํ”„๋กœ์ ํŠธ ์ด๋ฆ„์„ ์ง€์ •ํ•˜๊ณ  Finish ๋ฅผ ๋ˆ„๋ฅด๋ฉด ํ”„๋กœ์ ํŠธ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. Go ๋ฒ„์ „์ด ์—…๋ฐ์ดํŠธ๋˜๋ฉด์„œ GOPATH ๋ฐฉ์‹์— ํ”„๋กœ์ ํŠธ๋Š” ์ž˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์œผ๋กœ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

New Project 2021-08-15 17-20-32.png

์ž ์ƒˆ๋กœ์šด ์„ธ์ƒ์„ ๋งŒ๋‚  ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋‹ค๋ฉด ์ธ์‚ฌ๋ฅผ ํ•˜๋ฉฐ ์‹œ์ž‘ํ•ด๋ด…๋‹ˆ๋‹ค. main.go ํŒŒ์ผ์„ ๋งŒ๋“ค๊ณ  main ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•œ ๋’ค ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

package main
import "fmt"
func main() {
fmt.Print("Hello")
}
Hello, Go World!
Process finished with the exit code 0

๊ฐœ์ธ์ ์œผ๋กœ๋Š” ์ธ์‚ฌ๋งŒ ํ•œ ๋‹ค์„ฏ๋ฒˆ์งธ ํ•˜๋Š” ๊ฒƒ ๊ฐ™๋„ค์š” ๐Ÿ˜

์™ธ๋ถ€ ๋ฆฌ์†Œ์Šค ๊ฐ€์ ธ์˜ค๊ธฐ#

์ธ์‚ฌ๋งŒ ํ•˜๊ณ  ๋๋‚ด๊ธฐ๋Š” ์•„์‰ฌ์šฐ๋‹ˆ ํ•œ ๋ฐœ์ž๊ตญ๋งŒ ๋” ๊ฐ€๋ณผ๊นŒ์š”? ์ถ”ํ›„์— ์˜๋ฏธ์žˆ๋Š” ์•ฑ์„ ๋งŒ๋“ค๋ ค๋ฉด ์™ธ๋ถ€์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์˜ค๋Š”๊ฒŒ ํ•„์ˆ˜์ ์ž…๋‹ˆ๋‹ค. ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋‹ค๋ฉด, ๊ทธ ๋ฐ์ดํ„ฐ๋ฅผ ์ œ๊ณตํ•ด์ฃผ๋Š” ์„œ๋น„์Šค๋ฅผ ์ฐพ์•„๋ณด๊ณ  ๊ทธ ์„œ๋น„์Šค๊ฐ€ API ๋ฅผ ์ง€์›ํ•˜๋Š”์ง€ ํ™•์ธํ•ด๋ณด์„ธ์š”. ๋Œ€๋ถ€๋ถ„์˜ ์„œ๋น„์Šค๋“ค์€ API ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

API ๋ฌธ์„œ ํ™•์ธ#

์—ฌ๊ธฐ์„œ๋Š” ์š”์ฆ˜ ํ•ซํ•œ ์•”ํ˜ธํ™”ํ์˜ ํ˜„์žฌ ์‹œ์„ธ๋ฅผ ๊ฐ€์ง€๊ณ  ์™€๋ณด์ฃ . ์ €๋Š” ์—…๋น„ํŠธ ๊ฑฐ๋ž˜์†Œ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์—…๋น„ํŠธ API ๋ฌธ์„œ ์—์„œ ํ˜„์žฌ๊ฐ€ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋Š” ์—”๋“œํฌ์ธํŠธ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ฝ”๋”ฉํ•˜๊ธฐ ์ „์— ์ •๋ง๋กœ ๋ฐ์ดํ„ฐ๊ฐ€ ๋‚ด๋ ค์˜ค๋Š”์ง€ ํ™•์ธํ•ด๋ณผ๊นŒ์š”?

curl --request GET \
--url https://api.upbit.com/v1/ticker\?markets\=KRW-BTC \
--header 'Accept: application/json'
[{"market":"KRW-BTC","trade_date":"20210815","trade_time":"075919","trade_date_kst":"20210815","trade_time_kst":"165919","trade_timestamp":1629014359000,"opening_price":54817000.00000000,"high_price":55166000.0,"low_price":53420000.0,"trade_price":53614000.0,"prev_closing_price":54812000.00000000,"change":"FALL","change_price":1198000.00000000,"change_rate":0.0218565278,"signed_change_price":-1198000.00000000,"signed_change_rate":-0.0218565278,"trade_volume":0.022,"acc_trade_price":213592738229.775190000,"acc_trade_price_24h":559827073056.69978000,"acc_trade_volume":3918.44716516,"acc_trade_volume_24h":10269.53880782,"highest_52_week_price":81994000.00000000,"highest_52_week_date":"2021-04-14","lowest_52_week_price":11860000.00000000,"lowest_52_week_date":"2020-09-07","timestamp":1629014359797}]

์ž˜ ๊ฐ€์ง€๊ณ  ์˜ค๋„ค์š”. ๊ฐœ๋ฐœํ•˜๊ธฐ์— ์•ž์„œ ์ด๋Ÿฐ ๊ณผ์ •์€ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ์ฝ”๋”ฉ์„ ์ž˜๋ชปํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ชป ๊ฐ€์ง€๊ณ  ์˜จ ๊ฑด์ง€, ์•„๋‹ˆ๋ฉด ์„œ๋น„์Šค ์ž์ฒด์ ์œผ๋กœ ๋ฌธ์ œ๊ฐ€ ์žˆ์–ด์„œ ๋ชป๊ฐ€์ง€๊ณ  ์˜จ ๊ฒƒ์ธ์ง€ ํ™•์ธ์ด ํ•„์š”ํ•˜์ฃ . ์„œ๋น„์Šค๋Š” ๋ฌธ์ œ๊ฐ€ ์—†์œผ๋‹ˆ ์ด์ œ ์ œ๊ฐ€ ์ฝ”๋”ฉ๋งŒ ์ž˜ํ•˜๋ฉด ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์˜ค๊ฒ ๋„ค์š”. ๐Ÿคฉ

์‚ฌ์šฉํ•  ํŒจํ‚ค์ง€ ์ฐพ๊ณ  ๋ฌธ์„œ ํ™•์ธํ•˜๊ธฐ#

Go ์—์„œ๋Š” HTTP ์š”์ฒญ์„ ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ์š”? ๊ณ  ํŒจํ‚ค์ง€ ๋ฅผ ๋ชจ์•„๋†“์€ ์‚ฌ์ดํŠธ์— ๊ฐ€์„œ http ๋ฅผ ๊ฒ€์ƒ‰ํ•ด๋ด…๋‹ˆ๋‹ค. JAVA๋กœ ์น˜๋ฉด Maven Repository ๊ฐ™์€ ๊ณณ์ด๊ฒ ๋„ค์š”. ์˜ˆ์ œ๊ฐ€ ์นœ์ ˆํ•˜๊ฒŒ ์จ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ์‹์ƒํ•œ ์ธ์‚ฌ๋Š” ๊ทธ๋งŒํ•˜๊ณ  ์•”ํ˜ธํ™”ํ์˜ ๋Œ€์žฅ์ธ ๋น„ํŠธ์ฝ”์ธ์— ๊ฐ€๊ฒฉ์„ ๊ฐ€์ง€๊ณ  ์™€๋ณผ๊ป˜์š”.

package main
import (
"io/ioutil"
"net/http"
)
func main() {
resp, err := http.Get("https://api.upbit.com/v1/ticker?markets=KRW-BTC")
if err != nil {
panic(err)
}
defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
panic(err)
}
println(string(data))
}
[{"market":"KRW-BTC","trade_date":"20210815","trade_time":"084318","trade_date_kst":"20210815","trade_time_kst":"174318","trade_timestamp":1629016998000,"opening_price":54817000.00000000,"high_price":55166000.0,"low_price":53411000.0,"trade_price":53687000.0,"prev_closing_price":54812000.00000000,"change":"FALL","change_price":1125000.00000000,"change_rate":0.0205247026,"signed_change_price":-1125000.00000000,"signed_change_rate":-0.0205247026,"trade_volume":0.05957287,"acc_trade_price":239700491633.154070000,"acc_trade_price_24h":574757863109.85536000,"acc_trade_volume":4405.80968434,"acc_trade_volume_24h":10554.59700851,"highest_52_week_price":81994000.00000000,"highest_52_week_date":"2021-04-14","lowest_52_week_price":11860000.00000000,"lowest_52_week_date":"2020-09-07","timestamp":1629016998428}]

๋งˆ์น˜๋ฉฐ#

๊ฐ„๋‹จํ•œ ๋ช‡ ์ค„์— ์ฝ”๋“œ๋กœ ์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์™”์Šต๋‹ˆ๋‹ค. ์ด์ œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์˜ค๋Š” ๋ฒ•์„ ์•Œ์•˜์œผ๋‹ˆ ์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์—ฌ๊ธฐ์ €๊ธฐ์„œ ๊ฐ€์ง€๊ณ  ์™€์„œ ์š”๋ฆฌ์กฐ๋ฆฌ ๋š๋”ฑ๋š๋”ฑํ•˜๋ฉด ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ํ•˜๋Š” ์•ฑ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฒ ์–ด์š”. ๊ทธ๋Ÿฐ๋ฐ... ์ € JSON ๋ฌธ์ž์—ด๋กœ ๋œ ๋†ˆ์„ ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ์š”? Go ์— ์ € ๋ฐ์ดํ„ฐ๋ฅผ ์ด์˜๊ฒŒ ๋‹ด์•„๋†“๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์„๊นŒ์š”? ๋‹ค์Œ ๋ฒˆ์—๋Š” ์ด ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ฌด์ œ

๊ฐœ์š”#

๋‚ด ๋จธ๋ฆฌ ์†์— ํ๋ฅด๋Š” ์ƒ๊ฐ์„ ์ ์–ด๋ณธ๋‹ค.

์ƒ๊ฐ์˜ ํ๋ฆ„๋Œ€๋กœ ์ ๋Š”๋‹ค.#

๊ธ€์˜ ๊ตฌ์„ฑ#

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

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

140์ž#

140์ž๋ฅผ ์ƒ๊ฐํ•˜๋ฉด ๋– ์˜ค๋ฅด๋Š”๊ฒŒ ๊ธฐ์—…. ํŠธ์œ„ํ„ฐ, ๋‚˜๋Š” ํŠธ์œ„ํ„ฐ๋ฅผ ๋งŽ์ด ํ•˜์ง€ ์•Š์ง€๋งŒ ์•จ๋ก  ๋จธ์Šคํฌ ๋•๋ถ„์— ํŠธ์œ„ํ„ฐ๋กœ ๊ณต์œ ๋œ ์ •๋ณด๋ฅผ ๋‹ค๋ฅธ ๊ฒฝ๋กœ๋ฅผ ํ†ตํ•ด ๋งŽ์ด ์ ‘ํ•œ๋‹ค. ํŠธ์œ„ํ„ฐ๊ฐ€ ์„ฑ๊ณตํ–ˆ๋˜ ์ด์œ  ์ค‘์— ํ•˜๋‚˜๋Š” ์ด "140์ž" ๋กœ ํ•œ์ •์ง€์€ ํŠธ์œ—๋„ ํ•œ๋ชซํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ๊ธ€์ž ์ˆ˜์— ํ•œ๊ณ„ ๋•Œ๋ฌธ์— ์ •๋ณด์˜ ํ•ต์‹ฌ๋งŒ ๋‹ด์•„์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. (๋ฐฉ๊ธˆ ์•ˆ๊ฑฐ์ง€๋งŒ ํ•œ์ค‘์ผ์„ ์ œ์™ธํ•œ ๋‹ค๋ฅธ ๋‚˜๋ผ๋“ค์˜ ํŠธ์œ— ๊ธ€์ž์ˆ˜ ์ œํ•œ์€ 280์ž ๋ผ๊ณ  ํ•œ๋‹ค.) ๊ฐ‘์ž๊ธฐ ์™œ ํŠธ์œ„ํ„ฐ๊ฐ€ ํŠ€์–ด๋‚˜์™”๋ƒ๊ณ ? ๊ฐœ์š”๋Š” 140์ž ์ด๋‚ด๋กœ ์ ์ž! ๋ผ๋Š” ๊ทœ์น™์„ ๋งŒ๋“ค๋ฉด์„œ ๋– ์˜ฌ๋ž๋‹ค.

์ƒ๊ฐ์ด ๋‚ ๋ผ๋‹ค๋‹Œ๋‹ค.#

๋‚ด๊ฐ€ ๊ธ€์„ ์ ๊ฒ ๋‹ค๊ณ  ์ปดํ“จํ„ฐ ์•ž์— ์•‰์•˜์„ ๋•Œ, ๋ถ„๋ช…ํžˆ APY ์™€ ARP ์˜ ๋‹ค๋ฅธ ์  ์„ ์ •๋ฆฌํ•ด์•ผ๊ฒ ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋Š”๋ฐ, ๊ทธ๊ฑธ ์ ๋‹ค๋ณด๋‹ˆ ์•ต์ปค์— ๋Œ€ํ•œ ์ด์•ผ๊ธฐ๋ฅผ ํ•˜๊ณ  ์žˆ๊ณ , ์•ต์ปค๋ฅผ ์ ๋‹ค๋ณด๋‹ˆ ๋””ํŒŒ์ด์— ๋Œ€ํ•œ ๋‚ด์šฉ์„ ์ ๊ณ  ์žˆ๊ณ , ๊ธ€์˜ ๋‚ด์šฉ์ด ๋„ˆ๋ฌด ๋’ค์ฃฝ๋ฐ•์ฃฝ์ด๋ผ, ๋‚˜๋Š” ์™œ ์ด๋Ÿด๊นŒ ์ƒ๊ฐํ•˜๋‹ค๊ฐ€ ์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ๊ธ€์„ ์ž˜ ์“ฐ๋Š”์ง€๋ฅผ ์ฐพ์•„๋ณด๋‹ค๊ฐ€, ๊ฐ‘์ž๊ธฐ ์–ด์ œ ์‚ฐ ์œ ๋ฐ๋ฏธ ๊ฐ•์˜๊ฐ€ ์ƒ๊ฐ๋‚˜์„œ ๊ทธ๊ฑธ ์กฐ๊ธˆ ๋ณด๋‹ค๊ฐ€, ์•„ ๊ธ€ ์“ฐ๊ณ  ์‹ถ์€๋ฐ ์–ด๋–ป๊ฒŒํ•˜์ง€ ์‹ถ์–ด์„œ ์„ ํƒํ•œ ๋ฐฉ๋ฒ•์ด, ์ œ๋ชฉ์ด ์—†๋Š” ์ƒ๊ฐ ํ๋ฆ„ ์ ๊ธฐ๋‹ค. ์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ์ด ๋‚ ๋ผ๋‹ค๋‹ˆ๋Š” ์ƒ๊ฐ์„ ํ•˜๋‚˜์˜ ์ฃผ์ œ์— ๋ฌถ์–ด ๋†“์„ ์ˆ˜ ์žˆ์„๊นŒ?

๋‚ด๊ฐ€ ๋ฌด์–ธ๊ฐ€๋ฅผ ํ•™์Šตํ•˜๋Š” ๋ฐฉ๋ฒ•#

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

๊ทธ๋ ‡๊ฒŒ ํ•™์Šตํ•ด์•ผ ํ•  ๋Œ€์ƒ์ด ํŒŒ์•…๋˜๋ฉด, ๋‚˜๋Š” ๊ตฌ๊ธ€์— ๊ผญ alternative, compare, vs ์™€ ๊ฐ™์€ ๋‹จ์–ด๋ฅผ ์ž…๋ ฅํ•ด์„œ ๋‚ด๊ฐ€ ์ง€๊ธˆ๋ถ€ํ„ฐ ํ•™์Šตํ•  ๋…€์„์ด ์ตœ์ ์˜ ์†”๋ฃจ์…˜์ธ๊ฐ€? ๋ฅผ ํ™•์ธํ•œ๋‹ค. '์€์ด์•Œ์€ ์—†๋‹ค' ๋ผ๋Š” ๋ง์ฒ˜๋Ÿผ ๋ชจ๋“  ๊ฒƒ์„ ํ•ด๊ฒฐํ•˜๋Š” ๋‹จ ํ•˜๋‚˜์— ๋ฐฉ๋ฒ•์€ ์ž˜ ์กด์žฌํ•˜์ง€ ์•Š์ง€๋งŒ ์ด ๊ณผ์ •์—์„œ ๋‚ด ์„ฑ๊ฒฉ์— ๋” ์ž˜ ๋งž๊ฑฐ๋‚˜ ํ˜„์žฌ ์ƒํ™ฉ์— ๋” ์ ํ•ฉํ•œ ์†”๋ฃจ์…˜์„ ์ฐพ๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด๋‹ค.

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

์ด ์‹œ์ ์— ํ•„์š”ํ•œ ๊ฒŒ, ๊ฐœ๋ฐœ ์„œ์ ์ด๋‹ค. ๋‚˜๋Š” ๊ฐœ๋ฐœ ์„œ์ ์„ ๊ฝค๋‚˜ ์ข‹์•„ํ•˜๋Š”๋ฐ ์ผ๋‹จ ๋‚ด๊ฐ€ ๋ญ˜ ๋ชจ๋ฅด๋Š”์ง€ ๋ชจ๋ฅด๋Š” ๊ฒƒ์„ ๊นจ๋‹ซ๊ฒŒ ํ•ด์ฃผ๊ณ , ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธธ ๋•Œ ์–ธ์ œ๋“  ๋ฌผ์–ด๋ณผ ์ˆ˜ ์žˆ๋Š” ๋™๋ฃŒ ๊ฐ™์€ ์กด์žฌ๊ฐ€ ๋˜์–ด ์ฃผ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๊ฐœ๋ฐœ ์„œ์ ์„ ์ฝ๋‹ค๋ณด๋ฉด...

์ž ๊น ์ด๊ฑฐ ์ƒ๊ฐ์˜ ํ๋ฆ„์ธ๋ฐ ์ด ์ƒ๊ฐ์„ ๋„ˆ๋ฌด ๊นŠ๊ฒŒ ํ•œ๋“ฏ... ์กฐ๊ธˆ ๋” ์ •๋ฆฌํ•ด์„œ ๋ณ„๋„ ๊ธ€๋กœ ์ž‘์„ฑํ•ด๋ณด๊ธฐ๋กœ. ์•„๋งˆ ์œ„์™€ ๋น„์Šทํ•˜๊ฒŒ ์ž‘์„ฑํ•œ ๊ธ€์ด ์ € ๊นŠ์€ ์–ด๋”˜๊ฐ€์— ์ €์žฅ๋˜์–ด ์žˆ์„ ๋“ฏํ•˜๋‹ค.

๋ฌด๋…ธ๋™์›”์ด์ฒœ#

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

"๋ฌด๋…ธ๋™" ์ด๋ผ๊ณ  ํ•ด์„œ ์ผ์„ ํ•˜์ง€ ์•Š๋Š” ์‚ถ์„ ๋ชฉํ‘œ๋กœ ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. ๋‹ค๋งŒ ๋‚˜์˜ ๋…ธ๋™์œผ๋กœ ์ˆ˜์ž…์„ ๋งŒ๋“œ๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ, ๋‚˜์˜ ๋…ธ๋™์„ "์ง€์†์ ์ธ ์ˆ˜์ž…์„ ๋งŒ๋“ค์–ด ์ค„ ํŒŒ์ดํ”„ ๋ผ์ธ" ์„ ๋งŒ๋“œ๋Š”๋ฐ ์“ฐ๋Š” ์‚ถ์„ ์‚ด๊ณ  ์‹ถ๋‹ค. ์ฆ‰ ๋นต์„ ์ƒ์‚ฐํ•˜๋Š” ๊ธฐ๊ณ„์˜ ์‚ถ ๋ณด๋‹ค๋Š” ๋นต์„ ๋งŒ๋“œ๋Š” ๊ธฐ๊ณ„๋ฅผ ์„ค๊ณ„ํ•˜๊ณ  ๋งŒ๋“ค์–ด ๋Œ๋ฆฌ๋Š” ์‚ถ์„ ์‚ด๊ณ  ์‹ถ์€ ๊ฒƒ์ด์ง€, ์ผ ์•ˆํ•˜๋ฉด ๋ฌด๋ฃŒํ•ด์„œ ๊ทธ ๋˜ํ•œ ๊ทธ ๋‚˜๋ฆ„๋Œ€๋กœ์˜ ๊ณ ํ†ต์ธ๋“ฏใ…Ž

๋งˆ์น˜๋ฉฐ#

๊ทธ๋ƒฅ ๋‚ด ๋จธ๋ฆฌ ์†์— ํ๋ฅด๋Š” ์ƒ๊ฐ๋“ค์„ ๋‘์„œ์—†์ด ์ ์–ด๋ณด์•˜๋‹ค. ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์ฝ์–ด์ฃผ๊ธฐ ๋ฐ”๋ผ๊ธฐ ๋ณด๋‹ค๋Š” ๋‚ด ์ƒ๊ฐ์„ ์ •๋ฆฌํ•˜๋Š” ์ฐจ์›์—์„œ... ๊ทธ๋ž˜๋„ ์ •์‹ ์—†์ด ์ ๊ณ ๋‚˜๋‹ˆ ์ƒ๊ฐ์ด ์ข€ ์ •๋ฆฌ๋˜... ์—ˆ์œผ๋ฉด ์ข‹๊ฒ ์ง€๋งŒ, ํฌ๊ฒŒ ๋‹ฌ๋ผ์ง„ ๊ฒƒ์€ ์—†๋Š” ๊ฒƒ ๊ฐ™๋‹ค. ๊ทธ๋ž˜๋„ ๋ฏธ๋ž˜์˜ ๋‚ด๊ฐ€ ์ฝ์œผ๋ฉด ๊ทธ ๋• ๊ทธ๋žฌ์ง€ํ•˜๋ฉด์„œ ์›ƒ์„ ์ˆ˜ ์žˆ์„ํ…Œ๋‹ˆ... โ† ์ด ๋ฌธ์žฅ์„ ์ ์œผ๋ฉด์„œ ์•„์ฃผ ์˜ˆ์ „์— ์ž‘์„ฑํ–ˆ๋˜ ํ…€๋ธ”๋Ÿฌ ๋ธ”๋กœ๊ทธ์— ๋“ค์–ด๊ฐ€๋ดค๋Š”๋ฐ, ๊ทธ ๋•Œ๋„ ๋น„์Šทํ•œ ๊ธ€์„ ์ ์—ˆ๋‹ค. ์ƒ๊ฐ์ด ๊ฐ€๋“ํ•ด ๋ผ๋Š” ๊ธ€์ธ๋ฐ, ๋ฌด๋ ค 8๋…„ ์ „์ด๋‹ค. ๊ทธ ๋•Œ๋‚˜ ์ง€๊ธˆ์ด๋‚˜ ์™œ ํ•ญ์ƒ ์ƒ๊ฐ๋งŒ ๊ฐ€๋“ํ•œ๊ฑด์ง€... 8๋…„ ๋’ค์— ํ™ฉ๋Œ€์žฅ. ์ง€๊ธˆ๋„ ์ƒ๊ฐ์ด ๋งŽ๋‹ˆ?