[Spring][๊ฐœ๋…] ๐Ÿš€ Open API์™€ REST: ํ˜„๋Œ€ ์›น ์„œ๋น„์Šค์˜ ๋ชจ๋“  ๊ฒƒ! ๐Ÿงฉ

๊น€์ƒ์šฑยท2024๋…„ 10์›” 31์ผ
0
post-thumbnail

๐Ÿ”“ Open API๋ž€? ์–ธ์ œ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉ๋ ๊นŒ์š”?

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


๐Ÿ’ก Open API์˜ ํ™œ์šฉ ์‚ฌ๋ก€: ์–ด๋–ค ๋ฐ์ดํ„ฐ๊ฐ€ ์ œ๊ณต๋ ๊นŒ์š”?

  • ํฌํ„ธ ์„œ๋น„์Šค : ๋„ค์ด๋ฒ„์™€ ์นด์นด์˜ค ๊ฐ™์€ ํฌํ„ธ ์„œ๋น„์Šค์—์„œ๋Š” ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ API ํ˜•ํƒœ๋กœ ๊ณต๊ฐœํ•˜์—ฌ ์™ธ๋ถ€ ๊ฐœ๋ฐœ์ž๋“ค์ด ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
  • ๊ณต๊ณต๊ธฐ๊ด€ ๋ฐ์ดํ„ฐ : ๊ธฐ์ƒ์ฒญ, ์šฐ์ฒด๊ตญ๊ณผ ๊ฐ™์€ ๊ณต๊ณต๊ธฐ๊ด€๋„ Open API๋ฅผ ํ†ตํ•ด ๊ตํ†ต, ๋‚ ์”จ, ์šฐํŽธ ์„œ๋น„์Šค ๋“ฑ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ํŠนํžˆ ๊ณต๊ณต ๋ฐ์ดํ„ฐ ํฌํ„ธ (data.go.kr)์€ ๊ตํ†ต, ๋‚ ์”จ, ์šฐํŽธ ์„œ๋น„์Šค ๋“ฑ ์ผ์ƒ์ƒํ™œ์— ์œ ์šฉํ•œ ๊ณต๊ณต ๋ฐ์ดํ„ฐ๋ฅผ ํ’๋ถ€ํ•˜๊ฒŒ ์ œ๊ณตํ•˜์—ฌ ์™ธ๋ถ€ ํ”„๋กœ๊ทธ๋žจ์— ์‰ฝ๊ฒŒ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•ฉ๋‹ˆ๋‹ค! ๐ŸŒค๏ธ๐Ÿ“ฌ

๐Ÿ”— Open API์™€ REST ๋ฐฉ์‹: ์ด ๋‘˜์˜ ๊ด€๊ณ„๋Š”?

๋Œ€๋ถ€๋ถ„์˜ Open API๋Š” REST(Representational State Transfer) ๋ฐฉ์‹์„ ์ฑ„ํƒํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. REST๋Š” HTTP ํ”„๋กœํ† ์ฝœ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋ฉฐ, ๊ฐ„๋‹จํ•˜๊ณ  ํ‘œ์ค€ํ™”๋œ ํ˜ธ์ถœ ๋ฐฉ์‹์„ ์ œ๊ณตํ•˜์—ฌ ๋งŽ์€ Open API๊ฐ€ ์ด ๋ฐฉ์‹์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. REST ๋ฐฉ์‹์˜ ๊ฐ•์ ์€ ๊ฐ€๋ณ๊ณ  ๊ตฌ์กฐ๊ฐ€ ๋‹จ์ˆœํ•˜์—ฌ ๋‹ค์–‘ํ•œ ํ”Œ๋žซํผ์—์„œ ์‰ฝ๊ฒŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ธ๋ฐ์š”, ๋•๋ถ„์— ๊ฐœ๋ฐœ์ž๋“ค์€ ๋ณด๋‹ค ๋น ๋ฅด๊ณ  ๊ฐ„ํŽธํ•˜๊ฒŒ Open API๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ’ป๐Ÿ“ฑ


๐ŸŒ REST๋ž€? ์›น์„ ์›€์ง์ด๋Š” ์•„ํ‚คํ…์ฒ˜์˜ ํ•ต์‹ฌ ์›๋ฆฌ

REST(Representational State Transfer)๋Š” 2000๋…„ ๋กœ์ด ํ•„๋”ฉ์˜ ๋…ผ๋ฌธ์—์„œ ์ฒ˜์Œ์œผ๋กœ ๋“ฑ์žฅํ–ˆ์Šต๋‹ˆ๋‹ค. HTTP ํ‘œ์ค€ํ™”์— ๊ธฐ์—ฌํ•œ ํ•„๋”ฉ์€ ์›น์˜ ์žฅ์ ์„ ๊ทน๋Œ€ํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ์•„ํ‚คํ…์ฒ˜ ์„ค๊ณ„๋กœ์„œ REST๋ฅผ ์ œ์•ˆํ–ˆ์ฃ . ์ž์›์˜ ์ƒํƒœ๋ฅผ ํด๋ผ์ด์–ธํŠธ์— ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ์‹์ธ REST๋Š” ํŠนํžˆ, ํ•˜๋‚˜์˜ URI๊ฐ€ ๊ณ ์œ ํ•œ ๋ฆฌ์†Œ์Šค๋ฅผ ๋Œ€ํ‘œํ•œ๋‹ค๋Š” ์›์น™์„ ๊ฐ€์ง€๊ณ  ์žˆ์–ด, ํด๋ผ์ด์–ธํŠธ๊ฐ€ HTTP ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ž์›์„ ์†์‰ฝ๊ฒŒ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ๐ŸŒ


๐Ÿงฉ REST์˜ ๊ธฐ๋ณธ ์›๋ฆฌ: URI์™€ HTTP ๋ฉ”์„œ๋“œ๋กœ ์ž์› ๋‹ค๋ฃจ๊ธฐ

  • URI (Uniform Resource Identifier): REST์—์„œ๋Š” URI๊ฐ€ ํŠน์ • ์ž์›์„ ์‹๋ณ„ํ•˜๋Š” ๊ณ ์œ  ์ฃผ์†Œ์ž…๋‹ˆ๋‹ค. ์ด URI๋ฅผ ํ†ตํ•ด ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„์˜ ํŠน์ • ์ž์›์— ์ ‘๊ทผํ•˜๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • HTTP ๋ฉ”์„œ๋“œ: REST๋Š” HTTP ๋ฉ”์„œ๋“œ(GET, POST, PUT, DELETE)๋ฅผ ์‚ฌ์šฉํ•ด ๋‹ค์–‘ํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
    • GET: ์ž์› ์กฐํšŒ - ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์ž‘์—…
    • POST: ์ƒˆ๋กœ์šด ์ž์› ์ƒ์„ฑ - ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€
    • PUT: ๊ธฐ์กด ์ž์›์˜ ์ˆ˜์ • - ๋ฐ์ดํ„ฐ๋ฅผ ์—…๋ฐ์ดํŠธ
    • DELETE: ์ž์› ์‚ญ์ œ - ๋ฐ์ดํ„ฐ๋ฅผ ์‚ญ์ œ
  • ์ด๋Ÿฌํ•œ ๋ฉ”์„œ๋“œ์™€ URI์˜ ์กฐํ•ฉ์€ RESTfulํ•œ ์š”์ฒญ์„ ํ˜•์„ฑํ•˜๋ฉฐ, REST๋Š” ์ด๋ฅผ ํ†ตํ•ด ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๊ฐ„์˜ ์ž์› ์ œ์–ด๋ฅผ ๋‹จ์ˆœํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๐Ÿ”„

๐ŸŒŸ REST์˜ ๊ฐ•๋ ฅํ•œ ์žฅ์ : ๋‹จ์ˆœํ•จ๊ณผ ํ™•์žฅ์„ฑ

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


๐Ÿงฑ REST์˜ ํ•ต์‹ฌ ๊ตฌ์„ฑ ์š”์†Œ: ์ž์›, ํ–‰์œ„, ํ‘œํ˜„

REST ์•„ํ‚คํ…์ฒ˜๋Š” ์ž์›(Resource), ํ–‰์œ„(Verb), ํ‘œํ˜„(Representation)์ด๋ผ๋Š” ์„ธ ๊ฐ€์ง€ ๊ตฌ์„ฑ ์š”์†Œ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ์œผ๋ฉฐ, ๊ฐ ์š”์†Œ๋Š” API์˜ ์ค‘์š”ํ•œ ์—ญํ• ์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค. ํ•˜๋‚˜์”ฉ ์‚ดํŽด๋ณผ๊นŒ์š”? ๐ŸŒ


๐ŸŽฏ ์ž์› (Resource): REST์˜ ์ค‘์‹ฌ์ด ๋˜๋Š” ๋ฐ์ดํ„ฐ

  • ์ž์›์€ ํŠน์ • ๋ฐ์ดํ„ฐ๋‚˜ ์„œ๋น„์Šค ๋Œ€์ƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ์ •๋ณด, ์ƒํ’ˆ ๋ฐ์ดํ„ฐ ๋“ฑ์ด ์ž์›์˜ ๋Œ€ํ‘œ์ ์ธ ์˜ˆ์ž…๋‹ˆ๋‹ค.
  • URI (Uniform Resource Identifier)๋ฅผ ํ†ตํ•ด ๊ณ ์œ ํ•˜๊ฒŒ ์‹๋ณ„๋˜๋ฉฐ, ๋งˆ์น˜ ์›น ์ฃผ์†Œ์ฒ˜๋Ÿผ ๊ฐ ์ž์›์— ๊ณ ์œ ํ•œ ์ฃผ์†Œ๋ฅผ ๋ถ€์—ฌํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์›ํ•˜๋Š” ์ž์›์— ์‰ฝ๊ฒŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ๊ฒƒ์ด REST์˜ ํ•ต์‹ฌ์ž…๋‹ˆ๋‹ค. ๐ŸŒ

๐Ÿ”„ ํ–‰์œ„ (Verb): ์ž์›์— ๋Œ€ํ•œ ๋™์ž‘ ์ •์˜ํ•˜๊ธฐ

  • ํ–‰์œ„๋Š” ์ž์›์— ๋Œ€ํ•ด ์–ด๋–ค ๋™์ž‘์„ ํ•  ๊ฒƒ์ธ์ง€๋ฅผ ์˜๋ฏธํ•˜๋ฉฐ, HTTP ๋ฉ”์„œ๋“œ๋กœ ์ •์˜๋ฉ๋‹ˆ๋‹ค. REST๋Š” ์ด๋ฅผ ํ†ตํ•ด ์ž์›์˜ ์ƒํƒœ๋ฅผ ์กฐํšŒํ•˜๊ฑฐ๋‚˜ ๋ณ€๊ฒฝํ•˜๋Š” ํ‘œ์ค€ํ™”๋œ ๋ฐฉ์‹์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
    • GET: ์ž์›์„ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค.
    • POST: ์ž์›์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
    • PUT: ์ž์›์„ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.
    • DELETE: ์ž์›์„ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.
  • ์ด๋Ÿฌํ•œ ํ–‰์œ„๋Š” RESTfulํ•œ API ์„ค๊ณ„์—์„œ ์ž์›์— ๋Œ€ํ•œ ๋ช…ํ™•ํ•œ ์กฐ์ž‘ ๋ฐฉ์‹์„ ์ œ๊ณตํ•˜์—ฌ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐ„์˜ ์ƒํ˜ธ์ž‘์šฉ์„ ์ง๊ด€์ ์œผ๋กœ ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค. ๐Ÿš€

๐Ÿ“„ ํ‘œํ˜„ (Representation): ์ž์›์˜ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ๋‹ด์€ ๋ฐ์ดํ„ฐ ํ˜•ํƒœ

  • ํ‘œํ˜„์€ ์ž์›์„ ๋‹ค์–‘ํ•œ ํ˜•์‹์œผ๋กœ ํ‘œํ˜„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. JSON, XML, HTML ๋“ฑ ์—ฌ๋Ÿฌ ํ˜•ํƒœ๋กœ ์ž์›์ด ์ „์†ก๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํด๋ผ์ด์–ธํŠธ๋Š” ์ด๋ฅผ ํ†ตํ•ด ์ž์›์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์–ป๊ฑฐ๋‚˜ ๊ฐฑ์‹ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • RESTful API์—์„œ๋Š” ์ฃผ๋กœ JSON ํ˜•์‹์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. JSON์€ ๊ฐ€๋ณ๊ณ  ์‚ฌ๋žŒ์ด ์ฝ๊ธฐ ์‰ฌ์šด ํ˜•์‹์œผ๋กœ, ์›น ํ™˜๊ฒฝ์—์„œ์˜ ๋ฐ์ดํ„ฐ ๊ตํ™˜์— ์ด์ƒ์ ์ž…๋‹ˆ๋‹ค. ๐Ÿ“‘

๐Ÿ”„ ๊ธฐ์กด ์„œ๋น„์Šค vs REST ์„œ๋น„์Šค: ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ์˜ ์—ญํ•  ์ฐจ์ด

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


๐Ÿ–ฅ๏ธ ๊ธฐ์กด ์„œ๋น„์Šค: ์„œ๋ฒ„๊ฐ€ ๋ชจ๋“  ํ™”๋ฉด์„ ๊ตฌ์„ฑํ•˜๋Š” ๋ฐฉ์‹

  • ๋™์ž‘ ๋ฐฉ์‹: ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„์— ์š”์ฒญ์„ ๋ณด๋‚ด๋ฉด, ์„œ๋ฒ„๋Š” ๊ฐ ํ”Œ๋žซํผ์— ๋งž๋Š” ํ™”๋ฉด(View)์„ ์ง์ ‘ ์ƒ์„ฑํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ์— ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์›น์ด๋‚˜ ๋ชจ๋ฐ”์ผ์˜ ํ™”๋ฉด ์š”๊ตฌ์‚ฌํ•ญ์— ๋งž์ถฐ ์„œ๋ฒ„์—์„œ ๋ณ„๋„๋กœ ํ™”๋ฉด์„ ์ค€๋น„ํ•ด์•ผ ํ•˜๋Š” ๋ถ€๋‹ด์ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • ํŠน์ง•:
    • ํ”Œ๋žซํผ๋งˆ๋‹ค ๋งž์ถคํ˜• View๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•˜๋ฏ€๋กœ, ์„œ๋ฒ„๋Š” ๋‹ค์–‘ํ•œ ํ™”๋ฉด์„ ๊ด€๋ฆฌํ•˜๊ณ  ์ง€์›ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    • ์š”์ฒญ ๋ฐฉ์‹์— ์ œํ•œ์ด ์—†์œผ๋ฉฐ, ์—ฌ๋Ÿฌ ๋ฐฉ์‹์œผ๋กœ ์„œ๋ฒ„์— ์š”์ฒญ์ด ๋“ค์–ด์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์„œ๋ฒ„์—์„œ ๋ชจ๋“  ํ”Œ๋žซํผ์„ ์ง€์›ํ•˜๋ ค๋ฉด ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์–ด๋ ค์›Œ์ง€๊ณ  ํ™•์žฅ์„ฑ์—๋„ ์ œ์•ฝ์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. โš ๏ธ

๐Ÿ“Š REST ์„œ๋น„์Šค: ๋ฐ์ดํ„ฐ๋งŒ ์ œ๊ณตํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ™”๋ฉด์„ ๊ตฌ์„ฑ

  • ๋™์ž‘ ๋ฐฉ์‹: ์„œ๋ฒ„๋Š” ํด๋ผ์ด์–ธํŠธ์— ์š”์ฒญ์„ ๋ฐ›์œผ๋ฉด ๋ฐ์ดํ„ฐ(JSON ๋˜๋Š” XML ํ˜•ํƒœ)๋งŒ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ, ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ด ๋ฐ์ดํ„ฐ๋ฅผ ํ™œ์šฉํ•ด ํ•„์š”ํ•œ ํ™”๋ฉด์„ ์ง์ ‘ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ํŠน์ง•:
    • ์„œ๋ฒ„๋Š” JSON์ด๋‚˜ XML ํ˜•ํƒœ์˜ ๋ฐ์ดํ„ฐ ์ „์†ก์—๋งŒ ์ง‘์ค‘ํ•˜๋ฉฐ, ํด๋ผ์ด์–ธํŠธ๋Š” ์ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์ž์œ ๋กญ๊ฒŒ ํ™”๋ฉด์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • HTTP ๋ฉ”์„œ๋“œ(GET, POST, PUT, DELETE)๋ฅผ ์‚ฌ์šฉํ•ด ์š”์ฒญ์„ ํ‘œ์ค€ํ™”ํ•˜์—ฌ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ ๊ฐ„ ์ƒํ˜ธ์ž‘์šฉ์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.
    • ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ์˜ ์—ญํ• ์ด ๋ถ„๋ฆฌ๋˜๋ฏ€๋กœ ์œ ์—ฐ์„ฑ๊ณผ ํ™•์žฅ์„ฑ์ด ๋†’๊ณ , ์—ฌ๋Ÿฌ ํ”Œ๋žซํผ์—์„œ ๋™์ผํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„ ์ผ๊ด€์„ฑ ์žˆ๋Š” ํ™”๋ฉด ๊ตฌ์„ฑ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๐ŸŒ

๐Ÿ“ ๋น„๊ต ์š”์•ฝ: ๊ธฐ์กด ์„œ๋น„์Šค์™€ REST ์„œ๋น„์Šค์˜ ์ฐจ์ด

ํ•ญ๋ชฉ๊ธฐ์กด ์„œ๋น„์ŠคREST ์„œ๋น„์Šค
์„œ๋ฒ„ ์—ญํ• ๊ฐ ํ”Œ๋žซํผ์— ๋งž์ถ˜ View ์ƒ์„ฑ๋ฐ์ดํ„ฐ(JSON/XML)๋งŒ ๋ฐ˜ํ™˜
ํด๋ผ์ด์–ธํŠธ ์—ญํ• ์„œ๋ฒ„์—์„œ ์ œ๊ณตํ•œ View ์‚ฌ์šฉ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ํ™”๋ฉด ๊ตฌ์„ฑ
์œ ์ง€๋ณด์ˆ˜์„ฑ์„œ๋ฒ„์—์„œ ๋‹ค์–‘ํ•œ View ๊ด€๋ฆฌ ํ•„์š”ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ™”๋ฉด์„ ๊ตฌ์„ฑํ•˜๋ฏ€๋กœ ์„œ๋ฒ„ ๋ถ€๋‹ด ๊ฐ์†Œ
ํ™•์žฅ์„ฑํ”Œ๋žซํผ๋ณ„๋กœ ๊ฐœ๋ณ„ ๊ด€๋ฆฌ ํ•„์š”๋ชจ๋“  ํด๋ผ์ด์–ธํŠธ์— ๋™์ผํ•œ ๋ฐ์ดํ„ฐ ์ „์†ก, ํ”Œ๋žซํผ ๋…๋ฆฝ์„ฑ ์œ ์ง€

๐Ÿš€ REST ์„œ๋น„์Šค์˜ ์žฅ์ : ์œ ์—ฐ์„ฑ๊ณผ ํ™•์žฅ์„ฑ ๊ฐ•ํ™”

REST ์„œ๋น„์Šค๋Š” ๋ฐ์ดํ„ฐ๋งŒ ํด๋ผ์ด์–ธํŠธ์— ์ „๋‹ฌํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ™”๋ฉด ๊ตฌ์„ฑ์„ ์ฑ…์ž„์ง€๊ฒŒ ํ•จ์œผ๋กœ์จ ์„œ๋ฒ„์˜ ๋ถ€๋‹ด์„ ์ค„์ด๊ณ  ๋‹ค์–‘ํ•œ ํ”Œ๋žซํผ์— ์‰ฝ๊ฒŒ ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Open API์—์„œ๋„ ์ž์ฃผ ํ™œ์šฉ๋˜๋ฉฐ, RESTfulํ•œ ๊ตฌ์กฐ๋Š” ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๊ฐ„ ๋†’์€ ๋…๋ฆฝ์„ฑ๊ณผ ํ‘œ์ค€ํ™”๋œ ์ ‘๊ทผ ๋ฐฉ์‹์„ ํ†ตํ•ด ํ˜„๋Œ€์˜ ๋‹ค์–‘ํ•œ ์›น ์„œ๋น„์Šค์— ์œ ๋ฆฌํ•œ ์„ ํƒ์ž…๋‹ˆ๋‹ค. ๐Ÿ“ˆ


๐ŸŒ REST ๊ฐœ๋…๊ณผ URI ์„ค๊ณ„ ๊ทœ์น™: ๋ฐ์ดํ„ฐ ์ „์†ก์—์„œ ์ž์› ์‹๋ณ„๊นŒ์ง€

REST๋Š” ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๊ฐ„์˜ ๋ฐ์ดํ„ฐ ์ „์†ก๊ณผ ์ž์› ์ œ์–ด ๋ฐฉ์‹์„ ํ‘œ์ค€ํ™”ํ•˜์—ฌ ์›น ์„œ๋น„์Šค๋ฅผ ์„ค๊ณ„ํ•  ๋•Œ ํšจ์œจ์„ฑ๊ณผ ์ผ๊ด€์„ฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. REST์˜ ์ „์†ก ๋ฐฉ์‹๋ถ€ํ„ฐ URI ์„ค๊ณ„ ๊ทœ์น™๊นŒ์ง€ ์ฐจ๋ก€๋กœ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


๐Ÿ“ค REST์˜ ๊ธฐ๋ณธ ์ „์†ก ๋ฐฉ์‹: ๋ฐ์ดํ„ฐ๋งŒ ์ „์†ก

๊ธฐ์กด์˜ ์ „์†ก ๋ฐฉ์‹๊ณผ ๋‹ฌ๋ฆฌ, REST๋Š” ์ˆœ์ˆ˜ํ•œ ๋ฐ์ดํ„ฐ๋งŒ์„ ์ „์†กํ•˜์—ฌ ํ™”๋ฉด์„ ์„œ๋ฒ„์—์„œ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋ฐ์ดํ„ฐ ์ „์†ก์„ ํ‘œ์ค€ํ™”๋œ ๋ฐฉ์‹์œผ๋กœ ์ˆ˜ํ–‰ํ•ด ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ด๋ฅผ ํ™œ์šฉํ•˜์—ฌ ํ™”๋ฉด์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•์Šต๋‹ˆ๋‹ค. ๐Ÿ“Š


๐Ÿ”„ HTTP ๋ฉ”์„œ๋“œ๋ฅผ ํ™œ์šฉํ•œ CRUD ์ฒ˜๋ฆฌ

REST๋Š” HTTP ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ๋ฆฌ์†Œ์Šค์˜ CRUD ์ž‘์—…์„ ๋‹จ์ˆœํ•˜๊ณ  ๋ช…ํ™•ํ•˜๊ฒŒ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค:

  • GET: ๋ฐ์ดํ„ฐ ์กฐํšŒ
  • POST: ๋ฐ์ดํ„ฐ ์ƒ์„ฑ
  • PUT: ๋ฐ์ดํ„ฐ ์ˆ˜์ •
  • DELETE: ๋ฐ์ดํ„ฐ ์‚ญ์ œ

์ด ๋ฐฉ์‹์€ REST์˜ ์ž์› ๊ด€๋ฆฌ์™€ ๋™์ž‘์„ ์ง๊ด€์ ์œผ๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ, ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์‰ฝ๊ฒŒ ์ดํ•ดํ•˜๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.


๐Ÿ”— URI์™€ HTTP ๋ฉ”์„œ๋“œ๋กœ ์ž์› ์ œ์–ด

REST๋Š” URI๋ฅผ ํ†ตํ•ด ์ž์›์„ ๋ช…ํ™•ํžˆ ์‹๋ณ„ํ•˜๋ฉฐ, HTTP ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ด ์ž์›์— ๋Œ€ํ•œ ๋™์ž‘์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํŠน์ • ์ž์›์„ ๋‚˜ํƒ€๋‚ด๋Š” URI์™€ ํ•จ๊ป˜ GET, POST ๋“ฑ์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹น ์ž์›์— ์ ‘๊ทผํ•˜๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์ž์›์„ URL๋กœ ๊ฐ€๋ฆฌํ‚ค๊ณ  HTTP ๋ฉ”์„œ๋“œ๋กœ ์กฐ์ž‘ํ•˜๋Š” ์•„ํ‚คํ…์ฒ˜๋กœ, ๋ฐ์ดํ„ฐ ์ „์†ก๊ณผ ์กฐ์ž‘์˜ ํ‘œ์ค€ํ™”๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ๐Ÿ”‘


๐Ÿ—‚๏ธ ์ž์› ํ‘œํ˜„ ๋ฐฉ์‹: Collection๊ณผ Document

REST์—์„œ๋Š” ์ž์›์˜ ํ‘œํ˜„ ๋ฐฉ์‹์„ Collection(๋ฐ์ดํ„ฐ์˜ ์ง‘ํ•ฉ)๊ณผ Document(๊ฐœ๋ณ„ ๋ฐ์ดํ„ฐ)๋กœ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด:

  • http://www.example.com/sports/baseball/players/31์—์„œ Collection์€ "sports", "baseball", "players"์ด๊ณ ,
  • Document๋Š” ํŠน์ • ์ž์›์ธ "31"์ž…๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๊ณ„์ธต ๊ตฌ์กฐ๋Š” ๋ฐ์ดํ„ฐ ์ ‘๊ทผ์„ ์ฒด๊ณ„์ ์ด๊ณ  ์ผ๊ด€๋˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋ฉ๋‹ˆ๋‹ค. ๐Ÿ—ƒ๏ธ


๐Ÿ“ REST์˜ URI ์„ค๊ณ„ ๊ทœ์น™

REST์—์„œ๋Š” ํšจ์œจ์ ์ธ URI ์„ค๊ณ„๋ฅผ ์œ„ํ•ด ์•”๋ฌต์ ์ธ ๊ทœ์น™์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค:

  • ํ•˜์ดํ”ˆ(-)์€ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‚˜, ์–ธ๋”๋ฐ”(_)๋Š” ํ”ผํ•ด์„œ ๊ฐ€๋…์„ฑ์„ ๋†’์ž…๋‹ˆ๋‹ค.
  • ํŠน๋ณ„ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ์†Œ๋ฌธ์ž๋งŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • URI ๋งˆ์ง€๋ง‰์—๋Š” ์Šฌ๋ž˜์‹œ(/)๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์Šฌ๋ž˜์‹œ๋Š” ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ๊ตฌ๋ถ„ํ•  ๋•Œ์—๋งŒ ์‚ฌ์šฉ๋˜๋ฏ€๋กœ, ๋งˆ์ง€๋ง‰์— ์‚ฌ์šฉ ์‹œ ๋ถˆํ•„์š”ํ•œ ๊ณ„์ธต์ด ์ถ”๊ฐ€๋œ ๊ฒƒ์œผ๋กœ ํ•ด์„๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • URI์— ํ™•์žฅ์ž๋ฅผ ํฌํ•จํ•˜์ง€ ์•Š๊ณ , ๋ฐ์ดํ„ฐ ํ˜•์‹์€ ์ฃผ๋กœ ์š”์ฒญ ํ—ค๋”๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
  • ๋ช…์‚ฌํ˜• URI๋กœ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. REST๋Š” ์ž์› ์ค‘์‹ฌ์ด๋ฏ€๋กœ ์ž์›์„ ์ง๊ด€์ ์œผ๋กœ ํ‘œํ˜„ํ•˜๋Š” ๋ช…์‚ฌํ˜• URI๊ฐ€ ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค. ๐Ÿงพ

๐Ÿ”„ ๊ธฐ์กด ๋ฐฉ์‹ vs REST ๋ฐฉ์‹: CRUD ์ž‘์—…์—์„œ์˜ ์ฐจ์ด

๊ธฐ์กด ์›น ์ ‘๊ทผ ๋ฐฉ์‹๊ณผ REST API ๋ฐฉ์‹์€ CRUD ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์—์„œ ํฐ ์ฐจ์ด๋ฅผ ๋ณด์ž…๋‹ˆ๋‹ค. ํŠนํžˆ HTTP ๋ฉ”์„œ๋“œ์™€ URI ์„ค๊ณ„ ๊ตฌ์กฐ์—์„œ ๋‘๋“œ๋Ÿฌ์ง„ ์ฐจ์ด๊ฐ€ ๋‚˜ํƒ€๋‚˜๋ฉฐ, REST ๋ฐฉ์‹์€ ๋ณด๋‹ค ํ‘œ์ค€ํ™”๋˜๊ณ  ์ผ๊ด€์„ฑ ์žˆ๋Š” ๋ฐฉ์‹์œผ๋กœ ์ ‘๊ทผํ•ฉ๋‹ˆ๋‹ค. ํ•˜๋‚˜์”ฉ ๋น„๊ตํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


๐Ÿ–ฅ๏ธ ๊ธฐ์กด ๋ฐฉ์‹: GET๊ณผ POST๋กœ ์ž‘์—… ๊ตฌ๋ถ„

  • CRUD ์ž‘์—… ์ฒ˜๋ฆฌ:
    • ๊ธฐ์กด ๋ฐฉ์‹์—์„œ๋Š” ์ฃผ๋กœ GET๊ณผ POST ๋ฉ”์„œ๋“œ๋งŒ์„ ์‚ฌ์šฉํ•ด CRUD ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
    • ์ž‘์—… ๊ตฌ๋ถ„์€ URI์— action ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•ด ์ฒ˜๋ฆฌํ•˜๋ฉฐ, action=write, action=view ๋“ฑ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๊ฐ ์ž‘์—…์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
  • ์˜ˆ์‹œ:
    • Create (POST): /blog?action=write&id=tromment โ€“ action=write๋กœ ๊ธ€์“ฐ๊ธฐ ์ž‘์—…์„ ๋ช…์‹œํ•ฉ๋‹ˆ๋‹ค.
    • Read (GET): /blog?action=view&id=tromment&articleno=25 โ€“ action=view๋กœ ๊ธ€ ์กฐํšŒ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ฉฐ, id์™€ articleno๋กœ ํŠน์ • ๊ธ€์„ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค.
    • Update (POST): /blog?action=modify&id=tromment โ€“ action=modify๋ฅผ ํ†ตํ•ด ๊ธ€ ์ˆ˜์ • ์ž‘์—…์„ ๋ช…์‹œํ•ฉ๋‹ˆ๋‹ค.
    • Delete (GET): /blog?action=delete&id=tromment&articleno=25 โ€“ action=delete๋กœ ๊ธ€ ์‚ญ์ œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • ํŠน์ง•:
    • URI๋Š” ์ž‘์—…(Action)์„ ํ‘œ์‹œํ•˜๋Š” ์—ญํ• ์„ ํ•˜๋ฉฐ, ์ž‘์—…์„ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์œ„ํ•ด ์ฟผ๋ฆฌ์ŠคํŠธ๋ง์— action ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
    • HTTP ๋ฉ”์„œ๋“œ๋Š” ๊ตฌ๋ถ„ ์—†์ด GET๊ณผ POST๋งŒ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ, ๋‹ค์–‘ํ•œ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•  ๋•Œ ์ฝ”๋“œ์˜ ์ง๊ด€์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ”

๐ŸŒ REST ๋ฐฉ์‹: HTTP ๋ฉ”์„œ๋“œ๋กœ ์ž‘์—… ๊ตฌ๋ถ„

  • CRUD ์ž‘์—… ์ฒ˜๋ฆฌ:
    • REST ๋ฐฉ์‹์—์„œ๋Š” ์ž‘์—…์— ๋”ฐ๋ผ HTTP ๋ฉ”์„œ๋“œ(GET, POST, PUT, DELETE)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์š”์ฒญ์„ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. URI๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ๋‚˜ํƒ€๋‚ด๊ณ , HTTP ๋ฉ”์„œ๋“œ๊ฐ€ ์ž‘์—…์„ ๋ช…ํ™•ํžˆ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค.
  • ์˜ˆ์‹œ:
    • Create (POST): /blog/tromment โ€“ POST ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ๊ธ€์“ฐ๊ธฐ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉฐ, URI๋กœ ๋ฆฌ์†Œ์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ž‘์—…์„ ๋ช…ํ™•ํžˆ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
    • Read (GET): /blog/tromment/25 โ€“ GET ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ํŠน์ • ๊ธ€(tromment/25)์„ ์กฐํšŒํ•˜๋Š” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
    • Update (PUT): /blog/tromment โ€“ PUT ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ๊ธ€์„ ์ˆ˜์ •ํ•˜๋ฉฐ, URI๋Š” ์ˆ˜์ •ํ•  ๋Œ€์ƒ ๋ฆฌ์†Œ์Šค๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
    • Delete (DELETE): /blog/tromment/25 โ€“ DELETE ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ํŠน์ • ๊ธ€(tromment/25)์„ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.
  • ํŠน์ง•:
    • URI๋Š” ๋ช…์‚ฌํ˜•์œผ๋กœ ๋ฆฌ์†Œ์Šค๋งŒ์„ ๋‚˜ํƒ€๋‚ด๊ณ , HTTP ๋ฉ”์„œ๋“œ๋กœ ์ž‘์—…์„ ๋ช…ํ™•ํžˆ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์ž‘์—…์„ URI๊ฐ€ ์•„๋‹Œ ๋ฉ”์„œ๋“œ๋กœ ํ‘œํ˜„ํ•˜์—ฌ ์ผ๊ด€์„ฑ๊ณผ ์ง๊ด€์„ฑ์„ ๋†’์ด๊ณ  ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ๊ฐ•ํ™”ํ•ฉ๋‹ˆ๋‹ค. ๐Ÿ“ˆ

๐Ÿ“ ์š”์•ฝ: ๊ธฐ์กด ๋ฐฉ์‹๊ณผ REST ๋ฐฉ์‹์˜ CRUD ์ฒ˜๋ฆฌ ์ฐจ์ด

ํ•ญ๋ชฉ๊ธฐ์กด ๋ฐฉ์‹REST ๋ฐฉ์‹
HTTP ๋ฉ”์„œ๋“œ์ฃผ๋กœ GET๊ณผ POST ์‚ฌ์šฉGET, POST, PUT, DELETE ๋“ฑ ์ž‘์—…์— ๋งž๋Š” ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ
URI ๊ตฌ์กฐaction ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ž‘์—… ๊ตฌ๋ถ„๋ช…์‚ฌํ˜• URI๋กœ ๋ฆฌ์†Œ์Šค๋ฅผ ์ง€์นญํ•˜๊ณ , HTTP ๋ฉ”์„œ๋“œ๋กœ ์ž‘์—… ๊ตฌ๋ถ„
์œ ์ง€๋ณด์ˆ˜์„ฑ์ฟผ๋ฆฌ์ŠคํŠธ๋ง์œผ๋กœ ๋‹ค์–‘ํ•œ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•ด ์ง๊ด€์„ฑ์ด ๋‚ฎ์Œ์ž‘์—…๊ณผ ๋ฆฌ์†Œ์Šค๊ฐ€ ๋ถ„๋ฆฌ๋˜์–ด ์ผ๊ด€์„ฑ, ๊ฐ€๋…์„ฑ, ์œ ์ง€๋ณด์ˆ˜์„ฑ์ด ๋›ฐ์–ด๋‚จ

๐Ÿš€ REST ๋ฐฉ์‹์˜ ์žฅ์ : ์ผ๊ด€์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ ๊ฐ•ํ™”

REST ๋ฐฉ์‹์€ HTTP ๋ฉ”์„œ๋“œ์™€ URI ์„ค๊ณ„๋ฅผ ํ‘œ์ค€ํ™”ํ•˜์—ฌ ์„œ๋น„์Šค์˜ ์ผ๊ด€์„ฑ์„ ๋†’์ด๊ณ , ์œ ์ง€๋ณด์ˆ˜์„ฑ๊ณผ ๊ฐ€๋…์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค. ํŠนํžˆ, Open API์™€ ๊ฐ™์€ ํ™˜๊ฒฝ์—์„œ RESTful ์„ค๊ณ„๋Š” ๋‹ค์–‘ํ•œ ํด๋ผ์ด์–ธํŠธ์™€์˜ ์—ฐ๋™์„ ๋ณด๋‹ค ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด ํ˜„๋Œ€ ์›น ์„œ๋น„์Šค์˜ ํ•„์ˆ˜ ์š”์†Œ๋กœ ์ž๋ฆฌ ์žก์•˜์Šต๋‹ˆ๋‹ค. ๐ŸŒ


๐Ÿงฉ Jackson ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ: REST API์—์„œ JSON/XML ๋ณ€ํ™˜์˜ ํ•ต์‹ฌ ๋„๊ตฌ

Jackson ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์ž๋ฐ” ๊ฐ์ฒด๋ฅผ JSON์ด๋‚˜ XML ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ REST API์—์„œ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ํ•„์ˆ˜ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๋ฅผ ์ง๋ ฌํ™”ํ•˜๊ฑฐ๋‚˜ ์—ญ์ง๋ ฌํ™”ํ•˜์—ฌ, ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๊ฐ„ ์›ํ™œํ•œ ๋ฐ์ดํ„ฐ ์ „์†ก์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ“Š Jackson ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์ฃผ์š” ์—ญํ• : ์ง๋ ฌํ™”์™€ ์—ญ์ง๋ ฌํ™”

  • Jackson ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์ž๋ฐ” ๊ฐ์ฒด๋ฅผ JSON ๋˜๋Š” XML ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜(์ง๋ ฌํ™”)ํ•˜๊ณ , ๋ฐ˜๋Œ€๋กœ ๋ฌธ์ž์—ด์„ ์ž๋ฐ” ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜(์—ญ์ง๋ ฌํ™”)ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. REST API๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๋กœ JSON์ด๋‚˜ XML ํ˜•ํƒœ๋กœ ์ „์†กํ•˜๋ฏ€๋กœ, Jackson์„ ํ†ตํ•ด ์ด๋Ÿฌํ•œ ์ž‘์—…์„ ๊ฐ„ํŽธํ•˜๊ฒŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ“ˆ

๐Ÿงฑ ์ฃผ์š” Jackson ๋ชจ๋“ˆ ์†Œ๊ฐœ

  1. jackson-databind: JSON ๋ณ€ํ™˜์— ํ•„์ˆ˜์ ์ธ ๋ชจ๋“ˆ

    • ์—ญํ• : ์ž๋ฐ” ๊ฐ์ฒด์™€ JSON ๋ฌธ์ž์—ด ๊ฐ„ ๋ณ€ํ™˜์„ ์ˆ˜ํ–‰ํ•˜์—ฌ, JSON์„ ์‰ฝ๊ฒŒ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.
    • ์ด์œ : JSON์€ RESTful API์—์„œ ์ฃผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๋ฐ์ดํ„ฐ ํฌ๋งท์œผ๋กœ, ํด๋ผ์ด์–ธํŠธ-์„œ๋ฒ„ ๊ฐ„ ๋ฐ์ดํ„ฐ ๊ตํ™˜์— ์ด์ƒ์ ์ž…๋‹ˆ๋‹ค.
    • ์„ค์น˜ ๋งํฌ: jackson-databind Maven ์„ค์น˜
  2. jackson-dataformat-xml: XML ๋ณ€ํ™˜์„ ์œ„ํ•œ ๋ชจ๋“ˆ

    • ์—ญํ• : ์ž๋ฐ” ๊ฐ์ฒด์™€ XML ๋ฌธ์ž์—ด ๊ฐ„ ๋ณ€ํ™˜์„ ์ฒ˜๋ฆฌํ•˜์—ฌ, XML์„ ํ•„์š”๋กœ ํ•˜๋Š” ์‹œ์Šคํ…œ๊ณผ์˜ ํ˜ธํ™˜์„ฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
    • ์ด์œ : XML์€ ์ผ๋ถ€ ๋ ˆ๊ฑฐ์‹œ ์‹œ์Šคํ…œ๊ณผ ํŠน์ • ํ™˜๊ฒฝ์—์„œ ์—ฌ์ „ํžˆ ์‚ฌ์šฉ๋˜๋Š” ๋ฐ์ดํ„ฐ ํฌ๋งท์ž…๋‹ˆ๋‹ค.
    • ์„ค์น˜ ๋งํฌ: jackson-dataformat-xml Maven ์„ค์น˜

โš™๏ธ pom.xml ์„ค์ •์œผ๋กœ Jackson ์ถ”๊ฐ€ํ•˜๊ธฐ

Maven ํ”„๋กœ์ ํŠธ์— Jackson ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ ค๋ฉด pom.xml ํŒŒ์ผ์— Jackson ์˜์กด์„ฑ์„ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด jackson-databind ๋ชจ๋“ˆ์„ ์ถ”๊ฐ€ํ•˜์—ฌ JSON ๋ณ€ํ™˜์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>${jackson-databind-version}</version>
</dependency>

Tip: ${jackson-databind-version}์„ ์ตœ์‹  ๋ฒ„์ „ ๋ฒˆํ˜ธ๋กœ ๋Œ€์ฒดํ•˜์—ฌ Jackson ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ฐ€์ ธ์˜ค๋ฉด ๋ฉ๋‹ˆ๋‹ค!


๐Ÿ”– REST API ํ•„์ˆ˜ ์–ด๋…ธํ…Œ์ด์…˜ ์ •๋ฆฌ: ์—ญํ• ๊ณผ ํ™œ์šฉ๋ฒ•

REST API ๊ตฌํ˜„ ์‹œ ํ•„์ˆ˜์ ์ธ ์–ด๋…ธํ…Œ์ด์…˜๋“ค์€ ๋ฐ์ดํ„ฐ ์ „์†ก, URL ๊ฒฝ๋กœ ์ฒ˜๋ฆฌ, ํฌ๋กœ์Šค ๋„๋ฉ”์ธ ํ—ˆ์šฉ ๋“ฑ ์—ฌ๋Ÿฌ ๊ธฐ๋Šฅ์„ ๊ฐ„ํŽธํ•˜๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ๊ฐ์˜ ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด RESTful API์˜ ์ฃผ์š” ๊ธฐ๋Šฅ์„ ์†์‰ฝ๊ฒŒ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿงฉ @RestController: RESTful ์ปจํŠธ๋กค๋Ÿฌ ์„ ์–ธ

  • ์„ค๋ช…: @RestController๋Š” ํ•ด๋‹น ํด๋ž˜์Šค๊ฐ€ REST ๋ฐฉ์‹์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์ปจํŠธ๋กค๋Ÿฌ์ž„์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
  • ํŠน์ง•: @Controller์™€ @ResponseBody ๊ธฐ๋Šฅ์„ ๊ฒฐํ•ฉํ•˜์—ฌ, ํด๋ž˜์Šค ๋‚ด ๋ชจ๋“  ๋ฉ”์„œ๋“œ๊ฐ€ JSON ๋˜๋Š” XML ํ˜•ํƒœ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  • ์šฉ๋„: RESTful ์›น ์„œ๋น„์Šค์˜ API ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ์‚ฌ์šฉํ•˜๋ฉฐ, ๋ฐ์ดํ„ฐ๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ์™€ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›์„ ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๐Ÿ–ฅ๏ธ

๐Ÿ“ฆ @ResponseBody: ๋ฐ์ดํ„ฐ ์ง์ ‘ ์ „์†ก

  • ์„ค๋ช…: ๋ฉ”์„œ๋“œ์˜ ๋ฐ˜ํ™˜๊ฐ’์ด ๋ทฐ๋กœ ๋ Œ๋”๋ง๋˜์ง€ ์•Š๊ณ , ๋ฐ์ดํ„ฐ ์ž์ฒด๋กœ ํด๋ผ์ด์–ธํŠธ์— ์ „๋‹ฌ๋จ์„ ๋ช…์‹œํ•ฉ๋‹ˆ๋‹ค.
  • ํŠน์ง•: JSON, XML ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์‘๋‹ต ๋ณธ๋ฌธ์— ์ง์ ‘ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
  • ์šฉ๋„: ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ RESTful ๋ฐฉ์‹์œผ๋กœ ์‘๋‹ตํ•˜๋„๋ก ํ•  ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. @RestController๊ฐ€ ์„ ์–ธ๋œ ํด๋ž˜์Šค์—๋Š” ์ž๋™์œผ๋กœ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ๐Ÿ’ฌ

๐Ÿ”‘ @PathVariable: ๊ฒฝ๋กœ ๋ณ€์ˆ˜ ์ถ”์ถœ

  • ์„ค๋ช…: URL ๊ฒฝ๋กœ์— ํฌํ•จ๋œ ๋ณ€์ˆ˜๋ฅผ ๋ฉ”์„œ๋“œ์˜ ์ธ์ž๋กœ ์ „๋‹ฌํ•  ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • ํŠน์ง•: URI ํ…œํ”Œ๋ฆฟ ๋ณ€์ˆ˜๋ฅผ ๋ฉ”์„œ๋“œ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ”์ธ๋”ฉํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด /users/{id} ๊ฒฝ๋กœ์˜ {id}๋ฅผ ์ธ์ž๋กœ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์šฉ๋„: ์ž์› ์‹๋ณ„์„ ์œ„ํ•ด URI์— ํฌํ•จ๋œ ํŠน์ • ๊ฐ’์„ ์ถ”์ถœํ•˜๊ณ , ์ด๋ฅผ ํ†ตํ•ด ์ž์› ์ ‘๊ทผ์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ›ฃ๏ธ

๐ŸŒ @CrossOrigin: ํฌ๋กœ์Šค ๋„๋ฉ”์ธ ์š”์ฒญ ํ—ˆ์šฉ

  • ์„ค๋ช…: CORS(Cross-Origin Resource Sharing)์„ ํ—ˆ์šฉํ•˜์—ฌ ๋‹ค๋ฅธ ๋„๋ฉ”์ธ์—์„œ API์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
  • ํŠน์ง•: ๋ณด์•ˆ์ƒ ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…์„ ์šฐํšŒํ•˜์—ฌ ๋‹ค๋ฅธ ๋„๋ฉ”์ธ์—์„œ API์— ์ ‘๊ทผํ•˜๋„๋ก ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ์šฉ๋„: ๋‹ค๋ฅธ ๋„๋ฉ”์ธ์—์„œ AJAX ์š”์ฒญ์ด๋‚˜ API ํ˜ธ์ถœ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, http://example.com์—์„œ http://api.example.com์— ์š”์ฒญํ•  ๋•Œ ์ด๋ฅผ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. ๐Ÿ”“

๐Ÿ“ฅ @RequestBody: JSON ๋ฐ์ดํ„ฐ๋ฅผ ์ž๋ฐ” ๊ฐ์ฒด๋กœ ๋ฐ”์ธ๋”ฉ

  • ์„ค๋ช…: ํด๋ผ์ด์–ธํŠธ์—์„œ ์ „์†ก๋œ JSON ๋ฐ์ดํ„ฐ๋ฅผ ์ž๋ฐ” ๊ฐ์ฒด๋กœ ์ž๋™ ๋ณ€ํ™˜ํ•˜์—ฌ ๋ฉ”์„œ๋“œ์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
  • ํŠน์ง•: ์š”์ฒญ ๋ณธ๋ฌธ์— ์žˆ๋Š” JSON ๋ฐ์ดํ„ฐ๋ฅผ ์ž๋™์œผ๋กœ ํŠน์ • ์ž๋ฐ” ๊ฐ์ฒด ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • ์šฉ๋„: POST ์š”์ฒญ์œผ๋กœ ์ „๋‹ฌ๋œ JSON ๋ฐ์ดํ„ฐ๋ฅผ ์„œ๋ฒ„์—์„œ ์—”ํ‹ฐํ‹ฐ ๊ฐ์ฒด์— ๋ฐ”์ธ๋”ฉํ•˜์—ฌ ์ฒ˜๋ฆฌํ•  ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํผ ๋ฐ์ดํ„ฐ๋ฅผ JSON ํ˜•ํƒœ๋กœ ์ „์†ก๋ฐ›์•„ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ“ง

๐Ÿ“ ์š”์•ฝ

์–ด๋…ธํ…Œ์ด์…˜๊ธฐ๋Šฅ์šฉ๋„
@RestControllerRESTful API ์ปจํŠธ๋กค๋Ÿฌ๋กœ ์„ ์–ธ๋ฐ์ดํ„ฐ๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•  ๋•Œ
@ResponseBody๋ฐ์ดํ„ฐ๋ฅผ JSON, XML ํ˜•์‹์œผ๋กœ ์ง์ ‘ ์‘๋‹ตJSON, XML ์‘๋‹ต์„ ํ•„์š”๋กœ ํ•  ๋•Œ
@PathVariableURL ๊ฒฝ๋กœ์— ํฌํ•จ๋œ ๋ณ€์ˆ˜๋ฅผ ์ถ”์ถœํŠน์ • ์ž์› ์ ‘๊ทผ์„ ์œ„ํ•œ ๋ณ€์ˆ˜ ๋ฐ”์ธ๋”ฉ
@CrossOriginํฌ๋กœ์Šค ๋„๋ฉ”์ธ ์š”์ฒญ์„ ํ—ˆ์šฉ๋‹ค๋ฅธ ๋„๋ฉ”์ธ์˜ ์š”์ฒญ์„ ํ—ˆ์šฉํ•  ๋•Œ
@RequestBodyJSON ๋ฐ์ดํ„ฐ๋ฅผ ์ž๋ฐ” ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜JSON ํ˜•์‹์˜ ์š”์ฒญ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ”์ธ๋”ฉํ•  ๋•Œ

์ด ์–ด๋…ธํ…Œ์ด์…˜๋“ค์€ REST API์—์„œ ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ ์ „์†ก๊ณผ ์š”์ฒญ ์ฒ˜๋ฆฌ๋ฅผ ๊ฐ„ํŽธํ•˜๊ฒŒ ๋งŒ๋“ค์–ด, RESTful ๋ฐฉ์‹์˜ API ๊ฐœ๋ฐœ์„ ํšจ์œจ์ ์ด๊ณ  ์ผ๊ด€์„ฑ ์žˆ๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! ๐ŸŒ๐Ÿ“ฆ


๐Ÿš€ ํ•œ ๋ฒˆ์— ์ดํ•ดํ•˜๋Š” RESTful API๋กœ ํšŒ์› ๊ด€๋ฆฌํ•˜๊ธฐ! ๐Ÿ˜Ž

์•ˆ๋…•ํ•˜์„ธ์š”, ๊ฐœ๋ฐœ์ž ์—ฌ๋Ÿฌ๋ถ„! ์˜ค๋Š˜์€ Java์™€ JavaScript๋ฅผ ํ™œ์šฉํ•˜์—ฌ RESTful API๋กœ ํšŒ์› ๊ด€๋ฆฌ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ํฅ๋ฏธ์ง„์ง„ํ•œ ๋‚ด์šฉ์ด ๊ฐ€๋“ํ•˜๋‹ˆ ๋๊นŒ์ง€ ํ•จ๊ป˜ํ•ด ์ฃผ์„ธ์š”! ๐Ÿ’ช

๋ชฉ์ฐจ

  1. ํšŒ์› ๋ชฉ๋ก ์กฐํšŒ ๐Ÿ“
  2. ํšŒ์› ๋“ฑ๋ก โœ๏ธ
  3. ํšŒ์› ์ •๋ณด ์กฐํšŒ ๐Ÿ”
  4. ํšŒ์› ์ •๋ณด ์ˆ˜์ • ๐Ÿ› ๏ธ
  5. ํšŒ์› ์‚ญ์ œ โŒ
  6. ํšŒ์› ๋ชฉ๋ก ํ…Œ์ด๋ธ” ์ƒ์„ฑ ๐Ÿ—„๏ธ
  7. ๋งˆ๋ฌด๋ฆฌ ๐ŸŽฏ

1. ํšŒ์› ๋ชฉ๋ก ์กฐํšŒ ๐Ÿ“

์„œ๋ฒ„ ์‚ฌ์ด๋“œ(Java)

ํšŒ์› ๋ชฉ๋ก์„ ๊ฐ€์ ธ์˜ค๋Š” GET ์—”๋“œํฌ์ธํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

@GetMapping("/users")
public ResponseEntity<List<UserDto>> getAllUsers() {
    try {
        List<UserDto> users = userService.getAllUsers();
        if (users.isEmpty()) {
            return new ResponseEntity<>(HttpStatus.NO_CONTENT);
        } else {
            return new ResponseEntity<>(users, HttpStatus.OK);
        }
    } catch (Exception e) {
        return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
    }
}
  • ์„ค๋ช…: /users ๊ฒฝ๋กœ๋กœ ๋“ค์–ด์˜ค๋Š” GET ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜์—ฌ ๋ชจ๋“  ํšŒ์› ๋ชฉ๋ก์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • ํฌ์ธํŠธ:
    • ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์„ ๊ฒฝ์šฐ NO_CONTENT ์ƒํƒœ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    • ์˜ˆ์™ธ ๋ฐœ์ƒ ์‹œ INTERNAL_SERVER_ERROR ์ƒํƒœ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ(JavaScript)

์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ํšŒ์› ๋ชฉ๋ก์„ ๋ฐ›์•„์™€ ํ™”๋ฉด์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

fetch('/api/users')
    .then(response => {
        if (!response.ok) throw new Error('Network response was not ok');
        return response.json();
    })
    .then(users => renderUserList(users))
    .catch(error => console.error('Error fetching user list:', error));
  • ์„ค๋ช…: fetch๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ /api/users ์—”๋“œํฌ์ธํŠธ์— GET ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.
  • ํฌ์ธํŠธ:
    • ์‘๋‹ต ์ƒํƒœ๋ฅผ ํ™•์ธํ•˜๊ณ , ์ •์ƒ์ผ ๊ฒฝ์šฐ ๋ฐ์ดํ„ฐ๋ฅผ JSON์œผ๋กœ ํŒŒ์‹ฑํ•ฉ๋‹ˆ๋‹ค.
    • ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„ renderUserList ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ํ™”๋ฉด์— ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.

2. ํšŒ์› ๋“ฑ๋ก โœ๏ธ

์„œ๋ฒ„ ์‚ฌ์ด๋“œ(Java)

์ƒˆ๋กœ์šด ํšŒ์›์„ ๋“ฑ๋กํ•˜๋Š” POST ์—”๋“œํฌ์ธํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

@PostMapping("/users")
public ResponseEntity<UserDto> registerUser(@RequestBody UserDto userDto) {
    try {
        UserDto createdUser = userService.registerUser(userDto);
        return new ResponseEntity<>(createdUser, HttpStatus.CREATED);
    } catch (Exception e) {
        return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
    }
}
  • ์„ค๋ช…: /users ๊ฒฝ๋กœ๋กœ ๋“ค์–ด์˜ค๋Š” POST ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜์—ฌ ์ƒˆ๋กœ์šด ํšŒ์›์„ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.
  • ํฌ์ธํŠธ:
    • ์š”์ฒญ ๋ฐ”๋””๋กœ ์ „๋‹ฌ๋œ UserDto ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
    • ์„ฑ๊ณต ์‹œ CREATED ์ƒํƒœ์™€ ํ•จ๊ป˜ ์ƒ์„ฑ๋œ ํšŒ์› ์ •๋ณด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ(JavaScript)

์‚ฌ์šฉ์ž ์ž…๋ ฅ์„ ๋ฐ›์•„ ์„œ๋ฒ„๋กœ POST ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

document.getElementById('registerButton').addEventListener('click', () => {
    const userData = {
        username: document.getElementById('username').value,
        password: document.getElementById('password').value,
        email: document.getElementById('email').value,
    };

    fetch('/api/users', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify(userData),
    })
    .then(response => {
        if (!response.ok) throw new Error('Failed to register user');
        return response.json();
    })
    .then(newUser => {
        console.log('User registered:', newUser);
        // ์ถ”๊ฐ€ ์ž‘์—…: ํšŒ์› ๋ชฉ๋ก ๊ฐฑ์‹ , ์„ฑ๊ณต ๋ฉ”์‹œ์ง€ ํ‘œ์‹œ ๋“ฑ
    })
    .catch(error => console.error('Error registering user:', error));
});
  • ์„ค๋ช…: ํผ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ง‘ํ•˜์—ฌ ์„œ๋ฒ„์— ํšŒ์› ๋“ฑ๋ก ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.
  • ํฌ์ธํŠธ:
    • ์š”์ฒญ ํ—ค๋”์— Content-Type์„ application/json์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
    • ์‘๋‹ต์„ ๋ฐ›์•„ ํ•„์š”ํ•œ ํ›„์† ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

3. ํšŒ์› ์ •๋ณด ์กฐํšŒ ๐Ÿ”

์„œ๋ฒ„ ์‚ฌ์ด๋“œ(Java)

ํŠน์ • ํšŒ์›์˜ ์ •๋ณด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” GET ์—”๋“œํฌ์ธํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

@GetMapping("/users/{id}")
public ResponseEntity<UserDto> getUserById(@PathVariable Long id) {
    try {
        Optional<UserDto> user = userService.getUserById(id);
        return user.map(u -> new ResponseEntity<>(u, HttpStatus.OK))
                   .orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND));
    } catch (Exception e) {
        return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
    }
}
  • ์„ค๋ช…: /users/{id} ๊ฒฝ๋กœ๋กœ ๋“ค์–ด์˜ค๋Š” GET ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜์—ฌ ํŠน์ • ํšŒ์›์˜ ์ •๋ณด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • ํฌ์ธํŠธ:
    • ํšŒ์›์ด ์กด์žฌํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ NOT_FOUND ์ƒํƒœ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ(JavaScript)

ํšŒ์› ์ •๋ณด๋ฅผ ์š”์ฒญํ•˜์—ฌ ํ™”๋ฉด์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

function viewUserDetails(userId) {
    fetch(`/api/users/${userId}`)
        .then(response => {
            if (!response.ok) throw new Error('User not found');
            return response.json();
        })
        .then(user => {
            // ์‚ฌ์šฉ์ž ์ƒ์„ธ ์ •๋ณด๋ฅผ ํ™”๋ฉด์— ํ‘œ์‹œ
            document.getElementById('userDetail').innerText = `
                ID: ${user.id}
                ์ด๋ฆ„: ${user.username}
                ์ด๋ฉ”์ผ: ${user.email}
            `;
        })
        .catch(error => console.error('Error fetching user details:', error));
}
  • ์„ค๋ช…: ํšŒ์› ID๋ฅผ ์ด์šฉํ•˜์—ฌ ์„œ๋ฒ„์— ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ , ์‘๋‹ต ๋ฐ์ดํ„ฐ๋ฅผ ํ™”๋ฉด์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
  • ํฌ์ธํŠธ:
    • ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ํ–ฅ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.

4. ํšŒ์› ์ •๋ณด ์ˆ˜์ • ๐Ÿ› ๏ธ

์„œ๋ฒ„ ์‚ฌ์ด๋“œ(Java)

ํšŒ์› ์ •๋ณด๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” PUT ์—”๋“œํฌ์ธํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

@PutMapping("/users/{id}")
public ResponseEntity<UserDto> updateUser(@PathVariable Long id, @RequestBody UserDto userDto) {
    try {
        Optional<UserDto> updatedUser = userService.updateUser(id, userDto);
        return updatedUser.map(u -> new ResponseEntity<>(u, HttpStatus.OK))
                          .orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND));
    } catch (Exception e) {
        return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
    }
}
  • ์„ค๋ช…: /users/{id} ๊ฒฝ๋กœ๋กœ ๋“ค์–ด์˜ค๋Š” PUT ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜์—ฌ ํšŒ์› ์ •๋ณด๋ฅผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.
  • ํฌ์ธํŠธ:
    • ์กด์žฌํ•˜์ง€ ์•Š๋Š” ํšŒ์›์˜ ๊ฒฝ์šฐ NOT_FOUND ์ƒํƒœ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ(JavaScript)

์ˆ˜์ •๋œ ์ •๋ณด๋ฅผ ์„œ๋ฒ„๋กœ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.

function updateUser(userId) {
    const updatedData = {
        username: document.getElementById(`username_${userId}`).value,
        email: document.getElementById(`email_${userId}`).value,
    };

    fetch(`/api/users/${userId}`, {
        method: 'PUT',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify(updatedData),
    })
    .then(response => {
        if (!response.ok) throw new Error('Failed to update user');
        return response.json();
    })
    .then(user => {
        console.log('User updated:', user);
        // ์ถ”๊ฐ€ ์ž‘์—…: ํ™”๋ฉด ๊ฐฑ์‹ , ์„ฑ๊ณต ๋ฉ”์‹œ์ง€ ํ‘œ์‹œ ๋“ฑ
    })
    .catch(error => console.error('Error updating user:', error));
}
  • ์„ค๋ช…: ์ˆ˜์ •๋œ ํšŒ์› ์ •๋ณด๋ฅผ ์ˆ˜์ง‘ํ•˜์—ฌ ์„œ๋ฒ„์— PUT ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.
  • ํฌ์ธํŠธ:
    • ์š”์ฒญ ํ—ค๋” ์„ค์ •๊ณผ ์‘๋‹ต ์ฒ˜๋ฆฌ์— ์ฃผ์˜ํ•ฉ๋‹ˆ๋‹ค.

5. ํšŒ์› ์‚ญ์ œ โŒ

์„œ๋ฒ„ ์‚ฌ์ด๋“œ(Java)

ํšŒ์› ์‚ญ์ œ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” DELETE ์—”๋“œํฌ์ธํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

@DeleteMapping("/users/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
    try {
        boolean isDeleted = userService.deleteUser(id);
        if (isDeleted) {
            return new ResponseEntity<>(HttpStatus.NO_CONTENT);
        } else {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
    } catch (Exception e) {
        return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
    }
}
  • ์„ค๋ช…: /users/{id} ๊ฒฝ๋กœ๋กœ ๋“ค์–ด์˜ค๋Š” DELETE ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜์—ฌ ํšŒ์›์„ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.
  • ํฌ์ธํŠธ:
    • ์‚ญ์ œ ์„ฑ๊ณต ์‹œ ๋‚ด์šฉ ์—†์ด NO_CONTENT ์ƒํƒœ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ(JavaScript)

ํšŒ์› ์‚ญ์ œ ์š”์ฒญ์„ ์„œ๋ฒ„๋กœ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

function deleteUser(userId) {
    if (confirm('์ •๋ง๋กœ ์ด ํšŒ์›์„ ์‚ญ์ œํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?')) {
        fetch(`/api/users/${userId}`, {
            method: 'DELETE',
        })
        .then(response => {
            if (!response.ok) throw new Error('Failed to delete user');
            console.log('User deleted');
            // ์ถ”๊ฐ€ ์ž‘์—…: ํšŒ์› ๋ชฉ๋ก ๊ฐฑ์‹  ๋“ฑ
        })
        .catch(error => console.error('Error deleting user:', error));
    }
}
  • ์„ค๋ช…: ์‚ฌ์šฉ์ž ํ™•์ธ ํ›„ ์„œ๋ฒ„์— DELETE ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.
  • ํฌ์ธํŠธ:
    • ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์œ„ํ•ด ์‚ญ์ œ ์ „ ํ™•์ธ ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

6. ํšŒ์› ๋ชฉ๋ก ํ…Œ์ด๋ธ” ์ƒ์„ฑ ๐Ÿ—„๏ธ

ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ(JavaScript)

ํšŒ์› ๋ชฉ๋ก์„ ๋™์ ์œผ๋กœ ์ƒ์„ฑํ•˜์—ฌ ํ…Œ์ด๋ธ”์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

function renderUserList(users) {
    const tbody = document.getElementById('userTableBody');
    tbody.innerHTML = ''; // ๊ธฐ์กด ๋‚ด์šฉ์„ ์ง€์›๋‹ˆ๋‹ค.

    users.forEach(user => {
        const row = document.createElement('tr');

        // ID ์…€
        const idCell = document.createElement('td');
        idCell.textContent = user.id;
        row.appendChild(idCell);

        // ์ด๋ฆ„ ์…€
        const nameCell = document.createElement('td');
        nameCell.textContent = user.username;
        row.appendChild(nameCell);

        // ์ด๋ฉ”์ผ ์…€
        const emailCell = document.createElement('td');
        emailCell.textContent = user.email;
        row.appendChild(emailCell);

        // ์•ก์…˜ ์…€
        const actionCell = document.createElement('td');

        const viewButton = document.createElement('button');
        viewButton.textContent = '๋ณด๊ธฐ';
        viewButton.onclick = () => viewUserDetails(user.id);
        actionCell.appendChild(viewButton);

        const editButton = document.createElement('button');
        editButton.textContent = '์ˆ˜์ •';
        editButton.onclick = () => showEditForm(user.id);
        actionCell.appendChild(editButton);

        const deleteButton = document.createElement('button');
        deleteButton.textContent = '์‚ญ์ œ';
        deleteButton.onclick = () => deleteUser(user.id);
        actionCell.appendChild(deleteButton);

        row.appendChild(actionCell);

        tbody.appendChild(row);
    });
}
  • ์„ค๋ช…: ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ํšŒ์› ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ…Œ์ด๋ธ”์„ ๋™์ ์œผ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ํฌ์ธํŠธ:
    • ๊ฐ ํšŒ์›์— ๋Œ€ํ•ด ์ƒˆ๋กœ์šด ํ–‰๊ณผ ์…€์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
    • ์•ก์…˜ ๋ฒ„ํŠผ์„ ํ†ตํ•ด ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

7. ๋งˆ๋ฌด๋ฆฌ ๐ŸŽฏ

์—ฌ๊ธฐ๊นŒ์ง€ Java์™€ JavaScript๋ฅผ ํ™œ์šฉํ•˜์—ฌ RESTful API๋กœ ํšŒ์› ๊ด€๋ฆฌ ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ๊ธ€์„ ํ†ตํ•ด ๋‹ค์Œ์„ ์ดํ•ดํ•˜์…จ์„ ๊ฒ๋‹ˆ๋‹ค.

  • RESTful API์˜ ๊ธฐ๋ณธ ๊ฐœ๋…๊ณผ HTTP ๋ฉ”์„œ๋“œ์˜ ํ™œ์šฉ
  • Java(Spring Boot)๋กœ ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋กœ์ง ๊ตฌํ˜„
  • JavaScript๋กœ ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ์—์„œ ์„œ๋ฒ„์™€ ํ†ต์‹  ๋ฐ ๋™์  ํ™”๋ฉด ๊ตฌ์„ฑ
  • ์˜ˆ์™ธ ์ฒ˜๋ฆฌ์™€ ์‘๋‹ต ์ƒํƒœ ์ฝ”๋“œ์˜ ์ค‘์š”์„ฑ

์ด๋Ÿฌํ•œ ์ง€์‹์„ ์‹ค์ œ ํ”„๋กœ์ ํŠธ์— ์ ์šฉํ•˜๋ฉด ํšจ์œจ์ ์ด๊ณ  ์œ ์ง€๋ณด์ˆ˜ํ•˜๊ธฐ ์‰ฌ์šด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์•ž์œผ๋กœ๋„ ๊พธ์ค€ํ•œ ํ•™์Šต๊ณผ ์‹ค์ „ ๊ฒฝํ—˜์„ ํ†ตํ•ด ๋”์šฑ ์„ฑ์žฅํ•˜๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜์‹œ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค! ๐Ÿ˜Š


์ถ”๊ฐ€ ํŒ ๐Ÿ’ก

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

๊ถ๊ธˆํ•œ ์ ์ด๋‚˜ ๋„์›€์ด ํ•„์š”ํ•œ ๋ถ€๋ถ„์ด ์žˆ๋‹ค๋ฉด ์–ธ์ œ๋“ ์ง€ ๋Œ“๊ธ€๋กœ ๋‚จ๊ฒจ์ฃผ์„ธ์š”! ํ•จ๊ป˜ ์„ฑ์žฅํ•ด์š”! ๐Ÿš€


๐Ÿงฉ ResponseEntity<T> ํด๋ž˜์Šค: HTTP ์‘๋‹ต์˜ ๊ตฌ์„ฑ๊ณผ ์—ญํ• 

ResponseEntity<T>๋Š” ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์ œ๊ณตํ•˜๋Š” ํด๋ž˜์Šค๋กœ, HTTP ์‘๋‹ต์„ ์ƒํƒœ ์ฝ”๋“œ, ์‘๋‹ต ํ—ค๋”, ๋ณธ๋ฌธ ๋ฐ์ดํ„ฐ๋กœ ๊ตฌ์„ฑํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. REST API์—์„œ ์‚ฌ์šฉํ•˜๋ฉด ์„œ๋ฒ„๊ฐ€ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๊ตฌ์ฒด์ ์ด๊ณ  ๊ตฌ์กฐํ™”๋œ ์‘๋‹ต์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํด๋ž˜์Šค๊ฐ€ ์‘๋‹ต์˜ ์„ธ๋ถ€์ ์ธ ์š”์†Œ๋ฅผ ์–ด๋–ป๊ฒŒ ๊ตฌ์„ฑํ•˜๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค!


๐Ÿ” ResponseEntity<T>์˜ ์ฃผ์š” ๊ตฌ์„ฑ ์š”์†Œ

  1. ์ƒํƒœ ์ฝ”๋“œ (HTTP Status Code):

    • ์š”์ฒญ ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ƒํƒœ ์ฝ”๋“œ๋กœ, 200 OK, 404 NOT FOUND, 500 INTERNAL SERVER ERROR ๋“ฑ์˜ HTTP ์ƒํƒœ ์ฝ”๋“œ๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
    • ์ƒํƒœ ์ฝ”๋“œ๋Š” ์š”์ฒญ์˜ ์„ฑ๊ณต ์—ฌ๋ถ€๋‚˜ ์˜ค๋ฅ˜ ์ƒํ™ฉ์„ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ „๋‹ฌํ•˜๋Š” ์ค‘์š”ํ•œ ์ •๋ณด์ž…๋‹ˆ๋‹ค. ๐Ÿšฆ
  2. ์‘๋‹ต ํ—ค๋” (Response Header):

    • ์‘๋‹ต์— ํฌํ•จ๋  ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋กœ, Content-Type, Cache-Control, Authorization ๋“ฑ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์‘๋‹ต์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ๋ถ€๊ฐ€ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
    • ๊ฐ ํ—ค๋”๋Š” ์‘๋‹ต์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์ •๋ณด๋ฅผ ๋ช…ํ™•ํžˆ ํ•˜์—ฌ, ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๊ฐ„ ์ƒํ˜ธ์ž‘์šฉ์„ ํšจ์œจ์ ์œผ๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๐Ÿ“
  3. ๋ณธ๋ฌธ ๋ฐ์ดํ„ฐ (Response Body):

    • ์‹ค์ œ ์‘๋‹ต ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•˜๋Š” ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค. ๋ณดํ†ต JSON ๋˜๋Š” XML ๊ฐ™์€ ํ˜•์‹์œผ๋กœ ์‚ฌ์šฉ๋˜๋ฉฐ, ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์š”์ฒญํ•œ ์ •๋ณด๋ฅผ ๋ฐ˜ํ™˜ํ•  ๋•Œ ์ž์ฃผ ํ™œ์šฉ๋ฉ๋‹ˆ๋‹ค.
    • ResponseEntity์˜ ์ œ๋„ค๋ฆญ ํƒ€์ž… <T>๋ฅผ ํ†ตํ•ด ๋ณธ๋ฌธ ๋ฐ์ดํ„ฐ์˜ ํƒ€์ž…์„ ์œ ์—ฐํ•˜๊ฒŒ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ“ฆ

โš™๏ธ ์ œ๋„ค๋ฆญ ํƒ€์ž… <T>์˜ ์œ ์—ฐ์„ฑ

ResponseEntity<T>์—์„œ T๋Š” ์‘๋‹ต ๋ณธ๋ฌธ ๋ฐ์ดํ„ฐ์˜ ํƒ€์ž…์„ ์ •์˜ํ•˜๋ฉฐ, ๋‹ค์–‘ํ•œ ์ƒํ™ฉ์— ๋งž์ถฐ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

  • String: ๊ฐ„๋‹จํ•œ ๋ฌธ์ž์—ด ์‘๋‹ต
  • Object: ๊ฐ์ฒด๋ฅผ JSON ๋˜๋Š” XML๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•  ๋•Œ ์‚ฌ์šฉ
  • Dto (Data Transfer Object): ๊ตฌ์กฐํ™”๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•  ๋•Œ ์‚ฌ์šฉ
  • Void: ์‘๋‹ต ๋ณธ๋ฌธ์ด ํ•„์š” ์—†๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉ. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹จ์ˆœํžˆ ์„ฑ๊ณต/์‹คํŒจ ์—ฌ๋ถ€๋งŒ์„ ์ „๋‹ฌํ•  ๋•Œ ๋ณธ๋ฌธ์„ ๋น„์›Œ ๋‘˜ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿง‘โ€๐Ÿ’ป

๐Ÿ“ ResponseEntity ์‚ฌ์šฉ ์˜ˆ์‹œ

1. ๋ฐ์ดํ„ฐ ๋ฐ˜ํ™˜ ์˜ˆ์‹œ - ์„ฑ๊ณต์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•  ๊ฒฝ์šฐ:

public ResponseEntity<List<MemberDto>> getMembers() {
    List<MemberDto> members = memberService.getAllMembers();
    return new ResponseEntity<>(members, HttpStatus.OK); // ์ƒํƒœ ์ฝ”๋“œ 200๊ณผ ํ•จ๊ป˜ ๋ฐ์ดํ„ฐ ๋ฐ˜ํ™˜
}

2. ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์„ ๊ฒฝ์šฐ - NO_CONTENT๋กœ ์‘๋‹ต:

public ResponseEntity<Void> deleteMember(String id) {
    boolean deleted = memberService.deleteById(id);
    if (deleted) {
        return new ResponseEntity<>(HttpStatus.NO_CONTENT); // ์ƒํƒœ ์ฝ”๋“œ 204, ๋ณธ๋ฌธ ์—†์Œ
    } else {
        return new ResponseEntity<>(HttpStatus.NOT_FOUND); // ์ƒํƒœ ์ฝ”๋“œ 404 ๋ฐ˜ํ™˜
    }
}

๐Ÿ”ง ResponseEntity<T> ์ฃผ์š” ๊ธฐ๋Šฅ๊ณผ ์„ค์ • ์š”์†Œ: ์ƒํƒœ ์ฝ”๋“œ, ๋ณธ๋ฌธ, ํ—ค๋” ๊ด€๋ฆฌ

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


๐Ÿ› ๏ธ 1. ์ƒํƒœ ์ฝ”๋“œ ์„ค์ •: ์‘๋‹ต ๊ฒฐ๊ณผ ์•Œ๋ฆผ

  • ์„ค๋ช…: ์‘๋‹ต์— ํฌํ•จ๋  HTTP ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ์„ค์ •ํ•˜์—ฌ ์š”์ฒญ์˜ ์„ฑ๊ณต ์—ฌ๋ถ€๋‚˜ ์˜ค๋ฅ˜ ์ƒํƒœ๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
  • ์˜ˆ์ œ:
    ResponseEntity<String> response = new ResponseEntity<>(HttpStatus.OK);
    • ์—ฌ๊ธฐ์„œ HttpStatus.OK๋Š” ์ƒํƒœ ์ฝ”๋“œ 200์„ ์˜๋ฏธํ•˜๋ฉฐ, ์ด๋Š” ์š”์ฒญ์ด ์„ฑ๊ณต์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜์—ˆ์Œ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
  • ์ฃผ์š” ์ƒํƒœ ์ฝ”๋“œ:
    • 200 OK: ์š”์ฒญ์ด ์„ฑ๊ณต์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋จ.
    • 201 Created: ์ƒˆ๋กœ์šด ์ž์›์ด ์„ฑ๊ณต์ ์œผ๋กœ ์ƒ์„ฑ๋จ.
    • 404 Not Found: ์š”์ฒญํ•œ ์ž์›์„ ์ฐพ์„ ์ˆ˜ ์—†์Œ.
    • 500 Internal Server Error: ์„œ๋ฒ„์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•จ.
  • ์‚ฌ์šฉ ์šฉ๋„: ์ƒํƒœ ์ฝ”๋“œ๋Š” ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์‘๋‹ต์˜ ์ฒ˜๋ฆฌ ์ƒํƒœ๋ฅผ ์ง๊ด€์ ์œผ๋กœ ์ „๋‹ฌํ•˜์—ฌ, ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ›„์† ์ž‘์—…์„ ์ •ํ™•ํžˆ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•์Šต๋‹ˆ๋‹ค. ๐Ÿ“Š

๐Ÿ“ฆ 2. ๋ณธ๋ฌธ ์„ค์ •: ์‘๋‹ต ๋ฐ์ดํ„ฐ ์ „๋‹ฌ

  • ์„ค๋ช…: ์‘๋‹ต ๋ณธ๋ฌธ์— ํฌํ•จ๋  ๋ฐ์ดํ„ฐ๋ฅผ ์„ค์ •ํ•˜์—ฌ JSON, XML ๋“ฑ์˜ ํ˜•์‹์œผ๋กœ ์ง๋ ฌํ™”ํ•˜์—ฌ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
  • ์˜ˆ์ œ:
    ResponseEntity<List<MemberDto>> response = new ResponseEntity<>(list, HttpStatus.OK);
    • ์ด ์˜ˆ์ œ์—์„œ list๋Š” JSON ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜๋˜์–ด ์‘๋‹ต ๋ณธ๋ฌธ์— ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. HttpStatus.OK๋Š” ์ƒํƒœ ์ฝ”๋“œ 200์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
  • ์šฉ๋„: REST API์—์„œ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์š”์ฒญํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณธ๋ฌธ์œผ๋กœ ์ œ๊ณตํ•˜๋ฉฐ, ํŠนํžˆ ๊ฐ์ฒด๋‚˜ ๋ฆฌ์ŠคํŠธ ํ˜•์‹์˜ ๋ฐ์ดํ„ฐ๋ฅผ JSON/XML๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์ „๋‹ฌํ•˜๋Š” ๋ฐ ์ฃผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • ๊ธฐํƒ€: ๋ณธ๋ฌธ ๋ฐ์ดํ„ฐ๋Š” ์ œ๋„ค๋ฆญ ํƒ€์ž… <T>๋ฅผ ํ†ตํ•ด ๋‹ค์–‘ํ•œ ํƒ€์ž…์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์–ด, ์‘๋‹ต์˜ ์œ ์—ฐ์„ฑ์„ ๋†’์ž…๋‹ˆ๋‹ค. ๐Ÿ“„

๐Ÿ“ 3. ํ—ค๋” ์„ค์ •: ์‘๋‹ต ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ์ถ”๊ฐ€

  • ์„ค๋ช…: ์‘๋‹ต์˜ HTTP ํ—ค๋”๋ฅผ ์„ค์ •ํ•˜์—ฌ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋Œ€ํ‘œ์ ์ธ ํ—ค๋”๋กœ๋Š” Content-Type, Location ๋“ฑ์ด ์žˆ์œผ๋ฉฐ, ์ถ”๊ฐ€์ ์ธ ์ •๋ณด๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์ปค์Šคํ…€ ํ—ค๋”๋„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์˜ˆ์ œ:
    HttpHeaders headers = new HttpHeaders();
    headers.add("Custom-Header", "HeaderValue");
    ResponseEntity<String> response = new ResponseEntity<>("Body Content", headers, HttpStatus.OK);
    • Custom-Header๋ผ๋Š” ์ปค์Šคํ…€ ํ—ค๋”๊ฐ€ ์„ค์ •๋œ ์ƒํƒœ๋กœ "Body Content"๋ฅผ ๋ณธ๋ฌธ์œผ๋กœ, ์ƒํƒœ ์ฝ”๋“œ 200์„ ํฌํ•จํ•˜์—ฌ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • ์ฃผ์š” ํ—ค๋”:
    • Content-Type: ์‘๋‹ต ๋ฐ์ดํ„ฐ์˜ ์ฝ˜ํ…์ธ  ์œ ํ˜•์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ: application/json
    • Location: ๋ฆฌ์†Œ์Šค ์ƒ์„ฑ ์œ„์น˜๋ฅผ ๋‚˜ํƒ€๋‚ด๋ฉฐ, ์ฃผ๋กœ ์ƒํƒœ ์ฝ”๋“œ 201๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • ์‚ฌ์šฉ ์šฉ๋„: ํ—ค๋” ์„ค์ •์„ ํ†ตํ•ด ์‘๋‹ต์˜ ์†์„ฑ์„ ๋ช…ํ™•ํžˆ ์ •์˜ํ•˜๊ณ , ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์‘๋‹ต์„ ํ•ด์„ํ•˜๊ณ  ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ—‚๏ธ

๐Ÿ”ง ResponseEntity<T> ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐฉ์‹: ์ •์  ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•œ ๊ฐ„ํŽธํ•œ ์‘๋‹ต ๊ตฌ์„ฑ

ResponseEntity<T>๋Š” ๋‹ค์–‘ํ•œ ์ •์  ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ƒํƒœ ์ฝ”๋“œ์™€ ๋ณธ๋ฌธ, ํ—ค๋” ๋“ฑ์„ ๊ฐ„ํŽธํ•˜๊ฒŒ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์–ด REST API ์‘๋‹ต์„ ํšจ์œจ์ ์ด๊ณ  ๋ช…ํ™•ํ•˜๊ฒŒ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ƒ์„ฑ ๋ฐฉ์‹์„ ํ†ตํ•ด ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์„ ๋†’์ด๊ณ  ์ƒํ™ฉ์— ๋งž๋Š” ์‘๋‹ต์„ ์†์‰ฝ๊ฒŒ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ› ๏ธ 1. ๊ธฐ๋ณธ ์ƒ์„ฑ ๋ฐฉ์‹

  • ์„ค๋ช…: ResponseEntity ๊ฐ์ฒด๋Š” new ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ์ง์ ‘ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    new ResponseEntity<>(list, HttpStatus.OK);
  • ์Šคํ”„๋ง ์ œ๊ณต ์ •์  ๋ฉ”์„œ๋“œ: ResponseEntity์˜ ์ •์  ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, ๋” ๊ฐ„๊ฒฐํ•˜๊ฒŒ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿš€ 2. ์ฃผ์š” ์ •์  ๋ฉ”์„œ๋“œ (Static Methods)

๐ŸŸข OK (200)์™€ ๋ณธ๋ฌธ ์„ค์ •

  • ์„ค๋ช…: ResponseEntity.ok() ๋ฉ”์„œ๋“œ๋Š” ์ƒํƒœ ์ฝ”๋“œ 200(OK)์„ ์„ค์ •ํ•˜๋ฉฐ, ์‘๋‹ต ๋ณธ๋ฌธ์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์˜ˆ์ œ:
    return ResponseEntity.ok(list);
    • ์ด ์ฝ”๋“œ๋Š” HttpStatus.OK ์ƒํƒœ ์ฝ”๋“œ์™€ ํ•จ๊ป˜ list ๊ฐ์ฒด๋ฅผ ๋ณธ๋ฌธ์œผ๋กœ ํฌํ•จํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ„๊ฒฐํ•œ ์„ฑ๊ณต ์‘๋‹ต์„ ์œ„ํ•œ ์ตœ์ ์˜ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

๐Ÿ”ต ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ์ง์ ‘ ์„ค์ •ํ•˜๊ณ  ์ฒด์ด๋‹์œผ๋กœ ๋ณธ๋ฌธ ๋˜๋Š” ํ—ค๋” ์ถ”๊ฐ€

  • ์„ค๋ช…: ResponseEntity.status() ๋ฉ”์„œ๋“œ๋Š” ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ์„ค์ •ํ•œ ํ›„, ์ฒด์ด๋‹ ๋ฐฉ์‹์œผ๋กœ body() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ๋ณธ๋ฌธ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์˜ˆ์ œ:
    return ResponseEntity.status(HttpStatus.CREATED).body("Created Resource");
    • ์ด ์ฝ”๋“œ๋Š” ์ƒํƒœ ์ฝ”๋“œ 201(CREATED)์™€ ํ•จ๊ป˜ "Created Resource"๋ผ๋Š” ๋ณธ๋ฌธ์„ ์„ค์ •ํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ฃผ๋กœ ๋ฆฌ์†Œ์Šค ์ƒ์„ฑ ์„ฑ๊ณต์„ ๋‚˜ํƒ€๋‚ผ ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

โšช๏ธ No Content (204) - ๋ณธ๋ฌธ ์—†๋Š” ์‘๋‹ต

  • ์„ค๋ช…: ResponseEntity.noContent() ๋ฉ”์„œ๋“œ๋Š” ์ƒํƒœ ์ฝ”๋“œ 204(No Content)๋ฅผ ์„ค์ •ํ•˜๋ฉฐ, ๋ณธ๋ฌธ ์—†์ด ์‘๋‹ต์„ ๋ณด๋‚ผ ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • ์˜ˆ์ œ:
    return ResponseEntity.noContent().build();
    • ์ด ์ฝ”๋“œ๋Š” ์ƒํƒœ ์ฝ”๋“œ 204์™€ ํ•จ๊ป˜ ๋ณธ๋ฌธ ์—†์ด ๋ฐ˜ํ™˜๋˜๋ฉฐ, ์‚ญ์ œ ์ž‘์—… ์„ฑ๊ณต ํ›„ ์ถ”๊ฐ€ ๋ฐ์ดํ„ฐ๊ฐ€ ํ•„์š” ์—†์„ ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“ ์š”์•ฝ

  • ResponseEntity<T>๋Š” ๋‹ค์–‘ํ•œ ์ •์  ๋ฉ”์„œ๋“œ(ok(), status(), noContent())๋ฅผ ํ†ตํ•ด ์‘๋‹ต์˜ ์ƒํƒœ ์ฝ”๋“œ์™€ ๋ณธ๋ฌธ์„ ์ง๊ด€์ ์œผ๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ฒด์ด๋‹ ๋ฐฉ์‹์œผ๋กœ ๋ณธ๋ฌธ์ด๋‚˜ ํ—ค๋”๋ฅผ ๊ฐ„ํŽธํ•˜๊ฒŒ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์–ด ์ฝ”๋“œ๊ฐ€ ๋”์šฑ ์ฝ๊ธฐ ์‰ฌ์›Œ์ง€๊ณ  ์ƒํ™ฉ๋ณ„ ์‘๋‹ต ๊ตฌ์„ฑ์ด ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค.
  • ResponseEntity์˜ ์ •์  ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์„ ๋†’์ด๊ณ , ์‘๋‹ต ๊ตฌ์„ฑ์„ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ๋งŒ๋“ค์–ด RESTful API์˜ ์‘๋‹ต์„ ํšจ๊ณผ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๐ŸŒ

0๊ฐœ์˜ ๋Œ“๊ธ€

๊ด€๋ จ ์ฑ„์šฉ ์ •๋ณด