Two Approaches To Decoupling

Carson Gross

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

-Roy Fielding, https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_1_5

์ด ์—์„ธ์ด์—์„œ๋Š” ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋งฅ๋ฝ์—์„œ ๋‘ ๊ฐ€์ง€ ์œ ํ˜•์˜ ๊ฒฐํ•ฉ ํ•ด์ œ(Decoupling)๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค:

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

#๊ฒฐํ•ฉ(Coupling)

๊ฒฐํ•ฉ(Coupling)์€ ์†Œํ”„ํŠธ์›จ์–ด ์‹œ์Šคํ…œ์—์„œ ๋‘ ๊ฐœ์˜ ๋ชจ๋“ˆ์ด๋‚˜ ์‹œ์Šคํ…œ์˜ ์ธก๋ฉด์ด ๋†’์€ ์ƒํ˜ธ ์˜์กด์„ฑ์„ ๊ฐ€์ง€๋Š” ํŠน์„ฑ์„ ๋งํ•ฉ๋‹ˆ๋‹ค. **๊ฒฐํ•ฉ ํ•ด์ œ(Decoupling)**๋Š” ์ด์™€ ๊ด€๋ จ์ด ์—†๋Š” ๋ชจ๋“ˆ ๊ฐ„์˜ ์ƒํ˜ธ ์˜์กด์„ฑ์„ ์ค„์—ฌ ๋…๋ฆฝ์ ์œผ๋กœ ๋ฐœ์ „ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ํ–‰์œ„์ž…๋‹ˆ๋‹ค.

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

์ผ๋ฐ˜์ ์œผ๋กœ ๊ฒฝํ—˜์ด ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋“ค์€ ๊ฒฐํ•ฉ ํ•ด์ œ๋˜๊ณ  ์‘์ง‘๋ ฅ ์žˆ๋Š” ์‹œ์Šคํ…œ์„ ์ง€ํ–ฅํ•ฉ๋‹ˆ๋‹ค.

#JSON ๋ฐ์ดํ„ฐ API - ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ˆ˜์ค€์˜ ๊ฒฐํ•ฉ ํ•ด์ œ

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

์ด๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ˆ˜์ค€์˜ ๊ฒฐํ•ฉ ํ•ด์ œ์ž…๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๊ฒฐํ•ฉ ํ•ด์ œ์˜ ๊ฒฐ์ •๊ณผ ๊ตฌํ˜„์ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์ž์— ์˜ํ•ด ์ด๋ฃจ์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. JSON API๋Š” ์†Œํ”„ํŠธ์›จ์–ด์˜ ๋‘ ๋ถ€๋ถ„ ์‚ฌ์ด์— โ€œ๋‹จ๋‹จํ•œโ€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์ œ๊ฐ€ ์ข‹์•„ํ•˜๋Š” ์˜ˆ์‹œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ, https://example.com/account/12345์— GET ์—”๋“œํฌ์ธํŠธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์€ํ–‰์„ ์œ„ํ•œ ๊ฐ„๋‹จํ•œ JSON์„ ๊ณ ๋ คํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด API๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋‚ด์šฉ์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

HTTP/1.1 200 OK

{
    "account": {
        "account_number": 12345,
        "balance": {
            "currency": "usd",
            "value": -50.00
        },
        "status": "overdrawn"
    }
}

์ด ๋ฐ์ดํ„ฐ API๋Š” ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜, ๋ชจ๋ฐ”์ผ ํด๋ผ์ด์–ธํŠธ, ํƒ€์‚ฌ ๋“ฑ ์–ด๋–ค ํด๋ผ์ด์–ธํŠธ์—์„œ๋„ ์†Œ๋น„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํŠน์ • ํด๋ผ์ด์–ธํŠธ์— ์ข…์†๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

#JSON API๋ฅผ ํ†ตํ•œ ๊ฒฐํ•ฉ ํ•ด์ œ์˜ ์‹ค์ œ ์‚ฌ๋ก€

์ง€๊ธˆ๊นŒ์ง€๋Š” ์ž˜ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด ๊ฒฐํ•ฉ ํ•ด์ œ๊ฐ€ ์‹ค์ œ๋กœ๋Š” ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ• ๊นŒ์š”?

์šฐ๋ฆฌ์˜ ์—์„ธ์ด Splitting Your Data & Application APIs: Going Further์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ธ์šฉ๋ฌธ์„ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

์š”์ฆ˜ ๋‚ด ์ผ์—์„œ ๊ฐ€์žฅ ์–ด๋ ค์šด ๋ถ€๋ถ„์€ ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•ด API๋ฅผ ์„ค๊ณ„ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋Œ€ํ™”๋Š” ๋ถˆ๊ฐ€ํ”ผํ•˜๊ฒŒ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค:

Dev โ€“ ์ด ํ™”๋ฉด์—๋Š” ๋ฐ์ดํ„ฐ ์š”์†Œ x, y, z๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹คโ€ฆ ์ด ํ˜•์‹์˜ ์‘๋‹ต์„ ์ œ๊ณตํ•˜๋Š” API๋ฅผ ๋งŒ๋“ค์–ด ์ฃผ์‹ค ์ˆ˜ ์žˆ๋‚˜์š”? {x: , y:, z: }

Me โ€“ ์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค.

Jean-Jacques Dubray - https://www.infoq.com/articles/no-more-mvc-frameworks

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

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

์ด ๋ฌธ์ œ๋Š” ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ๋‹ค๋ฅธ ๋น„์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํด๋ผ์ด์–ธํŠธ๋ฅผ ์ง€์›ํ•  ๋•Œ ๋งŽ์€ JSON ๋ฐ์ดํ„ฐ API ๊ฐœ๋ฐœ์ž๋“ค์ด ์ง๋ฉดํ•˜๋Š” โ€œ๋ฒ„์ „ ๊ด€๋ฆฌ ์ง€์˜ฅโ€œ์œผ๋กœ ์ด์–ด์ง‘๋‹ˆ๋‹ค.

#ํ•ด๊ฒฐ์ฑ…: GraphQL

์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ•œ ๊ฐ€์ง€ ์ž ์žฌ์ ์ธ ํ•ด๊ฒฐ์ฑ…์€ GraphQL์„ ๋„์ž…ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. GraphQL์„ ์‚ฌ์šฉํ•˜๋ฉด API ํด๋ผ์ด์–ธํŠธ์˜ ์š”๊ตฌ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค API๋ฅผ ์ž์ฃผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์•„๋„ ๋˜๋Š” ํ›จ์”ฌ ๋” ํ‘œํ˜„๋ ฅ ์žˆ๋Š” JSON API๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์œ„์—์„œ ์„ค๋ช…ํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ํ•ฉ๋ฆฌ์ ์ธ ์ ‘๊ทผ ๋ฐฉ์‹์ด์ง€๋งŒ, ๋ช‡ ๊ฐ€์ง€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ API ๋ณ€๋™์„ฑ/๋ณด์•ˆ ์ ˆ์ถฉ์•ˆ ์—์„ธ์ด์—์„œ ์„ค๋ช…ํ•œ ๋ฐ”์™€ ๊ฐ™์ด, ๊ฐ€์žฅ ํฐ ๋ฌธ์ œ๋Š” ๋ณด์•ˆ์ž…๋‹ˆ๋‹ค.

Facebook์€ ํ—ˆ์šฉ ๋ชฉ๋ก์„ ์‚ฌ์šฉํ•˜์—ฌ GraphQL์ด ๋„์ž…ํ•˜๋Š” ๋ณด์•ˆ ๋ฌธ์ œ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ GraphQL์„ ์‚ฌ์šฉํ•˜๋Š” ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋“ค์ด ๊ด€๋ จ๋œ ๋ณด์•ˆ ์œ„ํ˜‘์„ ์ดํ•ดํ•˜์ง€ ๋ชปํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

#๋˜ ๋‹ค๋ฅธ ํ•ด๊ฒฐ์ฑ…: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐ ์ผ๋ฐ˜ ๋ฐ์ดํ„ฐ API ๋ถ„๋ฆฌ

๋˜ ๋‹ค๋ฅธ ์ ‘๊ทผ ๋ฐฉ์‹์œผ๋กœ๋Š”, Max Chernyak์ด ๊ทธ์˜ ๊ธฐ์‚ฌ Donโ€™t Build A General Purpose API To Power Your Own Front End์—์„œ ์ œ์•ˆํ•œ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์ด ์ ‘๊ทผ ๋ฐฉ์‹์€ ๋‘ ๊ฐ€์ง€ JSON API๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค:

์ด๊ฒƒ์€ ์—ฌ๋Ÿฌ๋ถ„์˜ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํ”„๋ก ํŠธ์—”๋“œ์™€ ์ด๋ฅผ ์ง€์›ํ•˜๋Š” ๋ฐฑ์—”๋“œ ์ฝ”๋“œ ๊ฐ„์˜ ๋ณธ์งˆ์ ์ธ ๊ฒฐํ•ฉ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ์‹ค์šฉ์ ์ธ ํ•ด๊ฒฐ์ฑ…์ด๋ฉฐ, ์ผ๋ฐ˜์ ์ธ GraphQL API์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ณด์•ˆ ์ ˆ์ถฉ์ ์„ ํฌํ•จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

#ํ•˜์ดํผ๋ฏธ๋””์–ด - ๋„คํŠธ์›Œํฌ ์•„ํ‚คํ…์ฒ˜ ๊ฒฐํ•ฉ ํ•ด์ œ

์ด์ œ ํ•˜์ดํผ๋ฏธ๋””์–ด API๊ฐ€ ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ์–ด๋–ป๊ฒŒ ๊ฒฐํ•ฉ ํ•ด์ œํ•˜๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์œ„์—์„œ ๋ณธ https://example.com/account/12345์— ๋Œ€ํ•œ ๋™์ผํ•œ GET ์š”์ฒญ์— ๋Œ€ํ•œ ์ž ์žฌ์ ์ธ ์‘๋‹ต์„ ๊ณ ๋ คํ•ด๋ณด์„ธ์š”:

HTTP/1.1 200 OK

<html>
  <body>
    <div>๊ณ„์ขŒ ๋ฒˆํ˜ธ: 12345</div>
    <div>์ž”์•ก: $100.00 USD</div>
    <div>๋งํฌ:
        <a href="/accounts/12345/deposits">์˜ˆ๊ธˆ</a>
        <a href="/accounts/12345/withdrawals">์ถœ๊ธˆ</a>
        <a href="/accounts/12345/transfers">์†ก๊ธˆ</a>
        <a href="/accounts/12345/close-requests">๊ณ„์ขŒ ํ•ด์ง€</a>
    </div>
  <body>
</html>

(๋„ค, ์ด๊ฒƒ์€ API ์‘๋‹ต์ž…๋‹ˆ๋‹ค. ์ด๋ฒˆ ๊ฒฝ์šฐ์—๋Š” ํ•˜์ดํผ๋ฏธ๋””์–ด ํ˜•์‹์˜ ์‘๋‹ต์ด๋ฉฐ, HTML๋กœ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค.)

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

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

๊ทธ๋ ‡๋‹ค๋ฉด, ์ด ๊ฒฝ์šฐ ๊ฒฐํ•ฉ ํ•ด์ œ๋Š” ์–ด๋””์—์„œ ์ผ์–ด๋‚˜๊ณ  ์žˆ์„๊นŒ์š”?

#REST & ์ผ๊ด€๋œ ์ธํ„ฐํŽ˜์ด์Šค

์ด ๊ฒฝ์šฐ ๊ฒฐํ•ฉ ํ•ด์ œ๋Š” ๋” ๋‚ฎ์€ ์ˆ˜์ค€์—์„œ ๋ฐœ์ƒํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ๋„คํŠธ์›Œํฌ ์•„ํ‚คํ…์ฒ˜ ์ˆ˜์ค€์—์„œ ์‹œ์Šคํ…œ ์ˆ˜์ค€์œผ๋กœ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ดํผ๋ฏธ๋””์–ด ์‹œ์Šคํ…œ์€ ํ•˜์ดํผ๋ฏธ๋””์–ด ํด๋ผ์ด์–ธํŠธ(์›น์˜ ๊ฒฝ์šฐ, ๋ธŒ๋ผ์šฐ์ €)๋ฅผ ํ•˜์ดํผ๋ฏธ๋””์–ด ์„œ๋ฒ„์—์„œ ๊ฒฐํ•ฉ ํ•ด์ œํ•˜๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ด๋Š” REST์˜ ์ผ๊ด€๋œ ์ธํ„ฐํŽ˜์ด์Šค ์ œ์•ฝ ์กฐ๊ฑด์„ ํ†ตํ•ด, ํŠนํžˆ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ƒํƒœ์˜ ์—”์ง„์œผ๋กœ์„œ์˜ ํ•˜์ดํผ๋ฏธ๋””์–ด(HATOEAS)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฃผ๋กœ ๋‹ฌ์„ฑ๋ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์Šคํƒ€์ผ์˜ ๊ฒฐํ•ฉ ํ•ด์ œ๋Š” ๋” ๋†’์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ˆ˜์ค€์—์„œ ๋” ๊ธด๋ฐ€ํ•œ ๊ฒฐํ•ฉ์„ ํ—ˆ์šฉํ•˜๋ฉด์„œ(์ด๋Š” ๋ณธ์งˆ์ ์ธ ๊ฒฐํ•ฉ์ผ ์ˆ˜ ์žˆ์Œ) ์ „์ฒด ์‹œ์Šคํ…œ์˜ ๊ฒฐํ•ฉ ํ•ด์ œ์˜ ์ด์ ์„ ์—ฌ์ „ํžˆ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.

#ํ•˜์ดํผ๋ฏธ๋””์–ด๋ฅผ ํ†ตํ•œ ๊ฒฐํ•ฉ ํ•ด์ œ์˜ ์‹ค์ œ ์‚ฌ๋ก€

์ด๋Ÿฌํ•œ ๊ฒฐํ•ฉ ํ•ด์ œ๊ฐ€ ์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์€ํ–‰ ๊ณ„์ขŒ์—์„œ ๋‹ค๋ฅธ ์€ํ–‰์œผ๋กœ ์†ก๊ธˆํ•˜๋Š” ๊ธฐ๋Šฅ๊ณผ ๊ณ„์ขŒ๋ฅผ ํ•ด์ง€ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ฑฐํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ด GET ์š”์ฒญ์— ๋Œ€ํ•œ ํ•˜์ดํผ๋ฏธ๋””์–ด ์‘๋‹ต์€ ์–ด๋–ป๊ฒŒ ๋ณด์ผ๊นŒ์š”?

HTTP/1.1 200 OK

<html>
  <body>
    <div>๊ณ„์ขŒ ๋ฒˆํ˜ธ: 12345</div>
    <div>์ž”์•ก: $100.00 USD</div>
    <div>๋งํฌ:
        <a href="/accounts/12345/deposits">์˜ˆ๊ธˆ</a>
        <a href="/accounts/12345/withdrawals">์ถœ๊ธˆ</a>
    </div>
  <body>
</html>

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

์ด๊ฒƒ์€ ํด๋ผ์ด์–ธํŠธ๋ฅผ ์†์ƒ์‹œํ‚ค์ง€ ์•Š๊ณ  API๋ฅผ ํฌ๊ฒŒ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

์ด ์œ ์—ฐ์„ฑ์€ REST-ful ๋„คํŠธ์›Œํฌ ์•„ํ‚คํ…์ฒ˜, ํŠนํžˆ HATEOAS์˜ ํ•ต์‹ฌ์ž…๋‹ˆ๋‹ค.

๋ณด์‹œ๋‹ค์‹œํ”ผ, ์šฐ๋ฆฌ์˜ ํ”„๋ก ํŠธ์—”๋“œ์™€ ๋ฐฑ์—”๋“œ ๊ฐ„์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ˆ˜์ค€ ๊ฒฐํ•ฉ์ด ํ›จ์”ฌ ๋” ๊ธด๋ฐ€ํ•ด์กŒ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ , REST-ful ํ•˜์ดํผ๋ฏธ๋””์–ด ์‹œ์Šคํ…œ์ด ์ œ๊ณตํ•˜๋Š” ์ผ๊ด€๋œ ์ธํ„ฐํŽ˜์ด์Šค ์ธก๋ฉด์—์„œ ๋„คํŠธ์›Œํฌ ์•„ํ‚คํ…์ฒ˜ ๊ฒฐํ•ฉ ํ•ด์ œ ๋•๋ถ„์— ์šฐ๋ฆฌ๋Š” ๋” ํฐ ์œ ์—ฐ์„ฑ์„ ๊ฐ–๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

#ํ•˜์ง€๋งŒ ์ด๊ฒƒ์€ ๋”์ฐํ•œ (๋ฐ์ดํ„ฐ) API์ž…๋‹ˆ๋‹ค!

๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ์ด ํ•˜์ดํผ๋ฏธ๋””์–ด API๊ฐ€ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—๋Š” ์œ ์—ฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ผ๋ฐ˜์ ์ธ API๋กœ์„œ๋Š” ๋”์ฐํ•˜๋‹ค๊ณ  ๋ฐ˜๋ฐ•ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

๋ฐ”๋กœ ์ด ์ด์œ  ๋•Œ๋ฌธ์— ์šฐ๋ฆฌ๋Š” Splitting Your Data & Application APIs: Going Further์—์„œ ํ•˜์ดํผ๋ฏธ๋””์–ด API์™€ ํ•จ๊ป˜ ์ผ๋ฐ˜์ ์ธ JSON API๋ฅผ ์ƒ์„ฑํ•  ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ•˜์ดํผ๋ฏธ๋””์–ด์˜ ์œ ์—ฐ์„ฑ์„ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ํ™œ์šฉํ•˜๋Š” ๋™์‹œ์— ๋ชจ๋ฐ”์ผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜, ํƒ€์‚ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋“ฑ์„ ์œ„ํ•œ ์ผ๋ฐ˜์ ์ธ JSON API๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

(์ฐธ๊ณ ๋กœ, ํ•˜์ดํผ๋ฏธ๋””์–ด ๊ธฐ๋ฐ˜ ๋ชจ๋ฐ”์ผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๋„ ์ข‹์€ ์„ ํƒ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!)

#๊ฒฐ๋ก 

์ด ์—์„ธ์ด์—์„œ๋Š” ๋‘ ๊ฐ€์ง€ ์œ ํ˜•์˜ ๊ฒฐํ•ฉ ํ•ด์ œ์— ๋Œ€ํ•ด ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค:

๊ทธ๋ฆฌ๊ณ  ํ•˜์ดํผ๋ฏธ๋””์–ด ๊ธฐ๋ฐ˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋” ๊ธด๋ฐ€ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ˆ˜์ค€ ๊ฒฐํ•ฉ์ด ์žˆ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ , ํ•˜์ดํผ๋ฏธ๋””์–ด ์‹œ์Šคํ…œ์ด ๋ณ€ํ™”์— ๋” ์ž˜ ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

</>