์ ๋ ํ์ดํผ๋ฏธ๋์ด API์ ๋ฐ์ดํฐ(JSON) API์ ๋ํด ๋ง์ด ๊ธ์ ์ผ์ต๋๋ค. ์ด ๊ธ๋ค์๋ ๋ ๊ฐ์ง์ ์ฐจ์ด์ , REST์ โ์ง์งโ ์๋ฏธ, ๊ทธ๋ฆฌ๊ณ HATEOAS๊ฐ ํ์ดํผ๋ฏธ๋์ด ํด๋ผ์ด์ธํธ์ ์ํธ์์ฉํ๋ ํ ๊ทธ๋ ๊ฒ ๋์์ง ์๋ค๋ ๋ด์ฉ์ด ํฌํจ๋์ด ์์ต๋๋ค.
์ข ์ข โREST๋ HTTP๋ฅผ ํตํ JSONโ์ด๋ผ๊ณ ์๊ฐํ๋ ์ฌ๋๋ค(์ฆ, ์ผ๋ฐ์ ์ธ ์ฌ๋๋ค)๊ณผ์ ๋ํ์์ ์ฌ๋ฌ ๊ฐ์ง ์ธ์ด์ ๋ฐ ๊ฐ๋ ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด์ผ ํ ๋๊ฐ ์์ต๋๋ค:
๋ง์ง๋ง ์์ ์ ์ผ๋ฐ์ ์ผ๋ก ๋จ์ผ, ์ผ๋ฐ์ ์ธ ๋ชฉ์ ์ JSON API๋ฅผ ์ฌ์ฉํ๋ ์ฌ๋๋ค์๊ฒ๋ ๋ฐ๋ณด์ฒ๋ผ ๋ณด์ผ ์ ์์ต๋๋ค. ์ ์ฌ๋ฌ ์ ํ์ ํด๋ผ์ด์ธํธ๋ฅผ ๋ง์กฑ์ํฌ ์ ์๋ ๋จ์ผ API๊ฐ ์๋๋ฐ ๋ ๊ฐ์ API๋ฅผ ๊ฐ์ ธ์ผ ํฉ๋๊น? ์ ๋ ์์ ์์ธ์ด์์ ์ด ์ง๋ฌธ์ ์ต์ ์ ๋คํด ๋ต๋ณํ๋ ค๊ณ ํ์ง๋ง, ํ์คํ ํ๋นํ ์ง๋ฌธ์ ๋๋ค.
์ผ๋ฐ์ ์ธ API๋ฅผ ๊ฐ๋ ๊ฒ๊ณผ ๋น๊ตํ ๋, ์ด ๋ฐฉ๋ฒ์ ์ฌ๋ฌ ๋ฉด์์ ์ถ๊ฐ์ ์ธ ์์ ์ฒ๋ผ ๋ณด์ผ ์ ์์ต๋๋ค.
์ด ๋ํ์์, ์ ์ ๋น์ทํ REST, ํ์ดํผ๋ฏธ๋์ด ๊ธฐ๋ฐ ์ ํ๋ฆฌ์ผ์ด์ ๋ฑ์ ๊ฒฌํด๋ฅผ ๋์ฒด๋ก ๋์ํ๋ ์ฌ๋์ด ์ข ์ข ๋ค์๊ณผ ๊ฐ์ ๋ง์ ํ ๊ฒ์ ๋๋ค.
โ์, ๊ฐ๋จํด์. ๊ทธ๋ฅ _์ฝํ ์ธ ํ์_์ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค. HTTP์ ๋ด์ฅ๋์ด ์์ด์!โ
์ผ๋ฐ์ ์ธ JSON API ์ ํธ๊ฐ๋ค๋ง ์์ธ์ํค๋ ๋ฐ ๊ทธ์น์ง ์๊ณ , ์ด๋ฒ์๋ ํ์ดํผ๋ฏธ๋์ด ์ ํธ๊ฐ ๋์ง๋ค๋ ์์ธ์ํฌ ์ ์๋ ๋ง์ ํ๊ฒ ์ต๋๋ค:
์ ๋ ๋๋ถ๋ถ์ ์ ํ๋ฆฌ์ผ์ด์ ์์ JSON๊ณผ HTML์ ๋ชจ๋ ๋ฐํํ๋ ๋ฐ ์์ด์ ์ฝํ ์ธ ํ์์ด ์ผ๋ฐ์ ์ผ๋ก ์ฌ๋ฐ๋ฅธ ์ ๊ทผ ๋ฐฉ์์ด๋ผ๊ณ ์๊ฐํ์ง ์์ต๋๋ค.
์ฐ์ , โ์ฝํ ์ธ ํ์โ์ด๋ ๋ฌด์์ผ๊น์?
์ฝํ
์ธ ํ์์ ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ๋ก๋ถํฐ ์๋ต์ ์ฝํ
์ธ ์ ํ์ ํ์ํ ์ ์๊ฒ ํด์ฃผ๋ HTTP์ ๊ธฐ๋ฅ์
๋๋ค.
HTTP์์์ ๊ตฌํ์ ๋ํ ์์ ํ ์ค๋ช
์ ์ด ์์ธ์ด์ ๋ฒ์๋ฅผ ๋ฒ์ด๋์ง๋ง, HTTP์์ ์ฝํ
์ธ ํ์์ ์ํ ๊ฐ์ฅ ์ ์๋ ค์ง ๋ฉ์ปค๋์ฆ์ธ
Accept
์์ฒญ ํค๋๋ฅผ ๊ณ ๋ คํด ๋ณด๊ฒ ์ต๋๋ค.
Accept
์์ฒญ ํค๋๋ ๋ธ๋ผ์ฐ์ ์ ๊ฐ์ ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ๋ก๋ถํฐ ์๋ต์์ ์๋ฝํ ์ ์๋ MIME
์ ํ์ ๋ํ๋ผ ์ ์๊ฒ ํด์ค๋๋ค.
์ด ํค๋์ ์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
Accept: text/html, application/xhtml+xml, application/xml;q=0.9, image/webp, */*;q=0.8
์ด Accept
ํค๋๋ ํด๋ผ์ด์ธํธ๊ฐ ์๋ฝํ ์ ์๋ ํ์์ ์๋ฒ์ ์๋ ค์ค๋๋ค. ์ ํธ๋๋ q
๊ฐ์ค์น ์์ธ์ ํตํด ํํ๋ฉ๋๋ค. ์์ผ๋์นด๋๋ ๋ณํ *
๋ก ํํ๋ฉ๋๋ค.
์ด ๊ฒฝ์ฐ ํด๋ผ์ด์ธํธ๋ ๋ค์๊ณผ ๊ฐ์ด ๋งํ๊ณ ์์ต๋๋ค:
๋๋ ๊ฐ์ฅ ๋ฐ๊ณ ์ถ์ ํ์์ text/html, application/xhtml+xml ๋๋ image/webp์ ๋๋ค. ๊ทธ๋ค์์ผ๋ก๋ application/xml์ ์ ํธํฉ๋๋ค. ๋ง์ง๋ง์ผ๋ก, ๋น์ ์ด ์ฃผ๋ ๋ฌด์์ด๋ ์๋ฝํ๊ฒ ์ต๋๋ค.
์๋ฒ๋ ์ด ์ ๋ณด๋ฅผ ์ฌ์ฉํ์ฌ ํด๋ผ์ด์ธํธ์๊ฒ ์ ๊ณตํ ์ต์ ์ ์ฝํ ์ธ ์ ํ์ ๊ฒฐ์ ํ ์ ์์ต๋๋ค.
์ด๊ฒ์ด โ์ฝํ ์ธ ํ์โ์ ํ์์ด๋ฉฐ, ๋ถ๋ช HTTP์ ํฅ๋ฏธ๋ก์ด ๊ธฐ๋ฅ์ ๋๋ค.
์ ๊ฐ ์๊ณ ์๋ ํ, Ruby On Rails ์ปค๋ฎค๋ํฐ๊ฐ ์ฒ์์ผ๋ก ์ฝํ ์ธ ํ์์ ๋๊ท๋ชจ๋ก ์ฌ์ฉํ์ฌ ๋์ผํ URL์์ HTML๊ณผ JSON(๋ฐ ๊ธฐํ) ํ์์ ์ ๊ณตํ๋ ๋ฐฉ์์ ๋์ ํ์ต๋๋ค.
Rails์์๋ ์ด ์์
์ ์ปจํธ๋กค๋ฌ์์ ์ฌ์ฉํ ์ ์๋ respond_to
ํฌํผ ๋ฉ์๋๋ฅผ ํตํด ์ํํฉ๋๋ค.
Rails์ ์ธ๋ถ์ ์ธ ๋ด์ฉ์ ์๋ตํ๊ณ , /contacts
์ ๋ํ HTTP GET
์์ฒญ์ด ContactsController
ํด๋์ค์ ํจ์๋ฅผ ํธ์ถํ๋ ์ํฉ์ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค. ์ด ํจ์๋ ๋ค์๊ณผ ๊ฐ์ด ์๊ฒผ์ต๋๋ค:
def index
@contacts = Contacts.all
respond_to do |format|
format.html # ๊ธฐ๋ณธ ๋ ๋๋ง ๋ก์ง
format.json { render json: @contacts }
end
end
respond_to
ํฌํผ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด, ํด๋ผ์ด์ธํธ๊ฐ ์์ Accept
ํค๋๋ฅผ ํฌํจํ์ฌ ์์ฒญ์ ๋ณด๋ผ ๋, ์ปจํธ๋กค๋ฌ๋ Rails ํ
ํ๋ฆฟ ์์คํ
์ ์ฌ์ฉํ์ฌ HTML ์๋ต์ ๋ ๋๋งํฉ๋๋ค.
๊ทธ๋ฌ๋ ํด๋ผ์ด์ธํธ๊ฐ Accept
ํค๋์ application/json
๊ฐ์ ํฌํจํ์ฌ ์์ฒญ์ ๋ณด๋ด๋ฉด, Rails๋ ์ฐ๋ฝ์ฒ๋ฅผ JSON ๋ฐฐ์ด๋ก ๋ ๋๋งํ์ฌ ํด๋ผ์ด์ธํธ์๊ฒ ๋ณด๋
๋๋ค.
์ด๊ฒ์ ๊ฝค ๊น๋ํ ํธ๋ฆญ์ ๋๋ค. ์ฐ๋ฝ์ฒ ์กฐํ์ ๊ฐ์ ๋ชจ๋ ์ปจํธ๋กค๋ฌ ๋ก์ง์ ๊ทธ๋๋ก ์ ์งํ๋ฉด์, ์ฝ๊ฐ์ Ruby/Rails ๋งค์ง์ ์ฌ์ฉํด ์ฝํ ์ธ ํ์์ ํตํด ๋ ๊ฐ์ง ๋ค๋ฅธ ์๋ต ํ์์ ๋ ๋๋งํ ์ ์์ต๋๋ค. ์ผ๋ฐ์ ์ธ Model/View/Controller ๋ก์ง์ ๊ฑฐ์ ์ถ๊ฐ ์์ ์ด ํ์ํ์ง ์์ต๋๋ค.
์ ์ฌ๋๋ค์ด ์ด ์์ด๋์ด๋ฅผ ์ข์ํ๋์ง ์ ์ ์์ต๋๋ค!
๊ทธ๋ ๋ค๋ฉด ์ ์ ๋ JSON๊ณผ HTML API๋ฅผ ๋ถ๋ฆฌํ๋ ๋ฐ ์ด ์ ๊ทผ ๋ฐฉ์์ด ์ข์ง ์๋ค๊ณ ์๊ฐํ ๊น์?
๊ทธ ์ด์ ๋ ์ ๊ฐ ์ด์ ์ ์ธ๊ธํ JSON API์ ํ์ดํผ๋ฏธ๋์ด(HTML) API ๊ฐ์ ์ฐจ์ด์ ์ ์์ต๋๋ค. ํนํ:
์ด ๋ชจ๋ ์ฐจ์ด์ ์ด ์ค์ํ๋ฉฐ, ๊ฐ๊ฐ์ ์ฐจ์ด์ ์ด ์ปจํธ๋กค๋ฌ ์ฝ๋์ ์ํฅ์ ๋ฏธ์ณ ๋ ๊ฐ์ง ๋ค๋ฅธ ๋ฐฉํฅ์ผ๋ก ๋๊ณ ๊ฐ์ง๋ง, ์ ๊ฐ ์ฝํ ์ธ ํ์์ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ฌ์ฉํ์ง ์๊ธฐ๋ก ์์ฃผ ์ ํํ๋ ์ด์ ๋ ์ฒซ ๋ฒ์งธ์ ๋ง์ง๋ง ํญ๋ชฉ์ ๋๋ค.
JSON API๋ ํด๋ผ์ด์ธํธ ์ฝ๋๊ฐ ์ ๋ขฐํ ์ ์๋ ์์ ์ ์ธ ์๋ํฌ์ธํธ ์ธํธ์ฌ์ผ ํฉ๋๋ค.
๋ฐ๋ฉด์ ํ์ดํผ๋ฏธ๋์ด API๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ์ฉ์ ์ธํฐํ์ด์ค ์๊ตฌ์ ๋ฐ๋ผ ํฌ๊ฒ ๋ณํํ ์ ์์ต๋๋ค.
์ด ๋ ๊ฐ์ง๋ ์ ์์ด์ง ์์ต๋๋ค.
๊ตฌ์ฒด์ ์ธ ์๋ฅผ ๋ค์ด๋ณด๊ฒ ์ต๋๋ค. ์ฐ๋ฝ์ฒ์ ์ธ๋ถ ์ ๋ณด๋ฅผ ๋ ๋๋งํ๋ ์๋ํฌ์ธํธ๊ฐ /contacts/:id
(์ฌ๊ธฐ์ :id
๋ ๋ ๋๋งํ ์ฐ๋ฝ์ฒ์ ID๋ฅผ ํฌํจํ๋ ๋งค๊ฐ๋ณ์)๋ผ๊ณ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค.
์ด ํ์ด์ง์๋ โ๊ด๋ จ ์ฐ๋ฝ์ฒโ๋ผ๋ UI ์น์
์ด ์๊ณ , ์ด ๊ด๋ จ ์ฐ๋ฝ์ฒ๋ฅผ ๊ณ์ฐํ๋ ๋ฐ ๋น์ฉ์ด ๋ง์ด ๋๋ ์ด์ ๊ฐ ์๋ค๊ณ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค.
์ด ์ํฉ์์๋ Lazy Loading ํจํด์ ์ฌ์ฉํ์ฌ ์ด๊ธฐ ์ฐ๋ฝ์ฒ ์ธ๋ถ ์ ๋ณด ํ๋ฉด์ด ๋ ๋๋ง๋ ํ ๊ด๋ จ ์ฐ๋ฝ์ฒ๋ฅผ ๋ก๋ํ๋๋ก ํ ์ ์์ต๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ฌ์ฉ์์๊ฒ ํ์ด์ง์ ์ง๊ฐ ์ฑ๋ฅ์ด ํฅ์๋ฉ๋๋ค.
์ด ๊ฒฝ์ฐ, ์ง์ฐ๋ ๋ก๋ ์ฝํ
์ธ ๋ฅผ /contacts/:id/related
์๋ํฌ์ธํธ์ ๋ฃ์ ์ ์์ต๋๋ค.
๊ทธ๋ฐ๋ฐ ๋์ค์ ๊ด๋ จ ์ฐ๋ฝ์ฒ์ ๊ณ์ฐ์ ์ต์ ํํ ์ ์๊ฒ ๋์์ ๋, ์ด ์์ ์์ /contacts/:id/related
์๋ํฌ์ธํธ๋ฅผ ์ ๊ฑฐํ๊ณ ๊ด๋ จ ์ฐ๋ฝ์ฒ ์ ๋ณด๋ฅผ ์ด๊ธฐ ํ์ด์ง ๋ ๋๋ง์ ํฌํจ์ํฌ ์ ์์ต๋๋ค.
์ด ๋ชจ๋ ๊ฒ์ด ํ์ดํผ๋ฏธ๋์ด API์๋ ๋ฌธ์ ๊ฐ ๋์ง ์์ต๋๋ค. ํ์ดํผ๋ฏธ๋์ด๋ ์ผ๊ด๋ ์ธํฐํ์ด์ค์ HATEOAS์ ํตํด ์ด๋ฌํ ๋ณํ๋ฅผ ์ฒ๋ฆฌํ๋๋ก _์ค๊ณ_๋์๊ธฐ ๋๋ฌธ์ ๋๋ค.
๊ทธ๋ฌ๋ JSON API๋ ๊ทธ๋ ์ง ์์ต๋๋ค.
JSON API๋ ์์ ์ ์ด์ด์ผ ํฉ๋๋ค. ์๋ํฌ์ธํธ๋ฅผ ์์์ ์ผ๋ก ์ถ๊ฐํ๊ฑฐ๋ ์ ๊ฑฐํ ์๋ ์์ต๋๋ค. ๋ค, ์ผ๋ถ ์๋ํฌ์ธํธ๋ JSON ๋๋ HTML๋ก ์๋ตํ ์ ์๊ณ , ๋ค๋ฅธ ์ผ๋ถ๋ HTML๋ก๋ง ์๋ตํ ์ ์์ง๋ง, ์ด ๋ฐฉ๋ฒ์ ๋ณต์กํด์ง๋๋ค. ์๋ฅผ ๋ค์ด, ์๋ชป๋ ์ฝ๋๊ฐ ๋ณต์ฌ๋์ด ์๋ชป๋ ๊ณณ์ ๋ถ์ฌ๋ฃ์ด์ง๋ฉด ์ด๋ป๊ฒ ๋ ๊น์?
์ด ๋ชจ๋ ๊ฒ์ ๊ณ ๋ คํ ๋, ์๋ ์ ํ๊ณผ ๊ฐ์ ์์๋ฅผ ๊ฐ์ํ์ฌ JSON API์ ํ์ดํผ๋ฏธ๋์ด API ์ฌ์ด์ ๊ด์ฌ์ฌ ๋ถ๋ฆฌ๊ฐ ์์ด์ผ ํ๋ค๊ณ ๊ฐ๋ ฅํ ์ฃผ์ฅํ ์ ์์ต๋๋ค.
(๋ค, ํ๋์ ์ง์ญ์ฑ์ด๋ผ๋ ์ฉ์ด๋ฅผ ๋ง๋ ์ฌ๋์ด SoC ์ฃผ์ฅ์ ํ๋ค๋ ๊ฒ์ ์ญ์ค์ ์ด๋ผ๋ ๊ฒ์ ์๊ณ ์์ต๋๋ค.)
๋์์ ์ ๊ฐ API ๋ถ๋ฆฌ์์ ์ฃผ์ฅํ๋ ๋๋ก, ์ฆ, API๋ฅผ ๋ถ๋ฆฌํ๋ ๊ฒ์ ๋๋ค. ์ด๋ JSON API์ ํ์ดํผ๋ฏธ๋์ด(HTML) API์ ๋ํด ์๋ก ๋ค๋ฅธ ๊ฒฝ๋ก(๋๋ ํ์ ๋๋ฉ์ธ ๋ฑ)๋ฅผ ์ ๊ณตํ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
๋ค์ ์ฐ๋ฝ์ฒ API๋ก ๋์๊ฐ์, ์ฐ๋ฆฌ๋ ๋ค์๊ณผ ๊ฐ์ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง ์ ์์ต๋๋ค:
/api/v1/contacts
์ ์์นํฉ๋๋ค./contacts
์ ์์นํฉ๋๋ค.์ด ๊ตฌ์กฐ๋ ๋ ๊ฐ์ ๋ค๋ฅธ ์ปจํธ๋กค๋ฌ๋ฅผ ์์ํ๋ฉฐ, ์ ๋ ์ด๊ฒ์ด ์ข์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. JSON API ์ปจํธ๋กค๋ฌ๋ JSON API์ ์๊ตฌ ์ฌํญ์ ๊ตฌํํ ์ ์์ต๋๋ค: ์๋ ์ ํ, ์์ ์ฑ, ๊ทธ๋ฆฌ๊ณ GraphQL๊ณผ ๊ฐ์ ํํ๋ ฅ ์๋ ์ฟผ๋ฆฌ ๋ฉ์ปค๋์ฆ.
ํํธ, ํ์ดํผ๋ฏธ๋์ด API(์ฌ์ค์ ํ์ดํผ๋ฏธ๋์ด ๊ธฐ๋ฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ์๋ํฌ์ธํธ)๋ ์ฌ์ฉ์ ์ธํฐํ์ด์ค ์๊ตฌ ์ฌํญ์ ๋ฐ๋ผ ํฌ๊ฒ ๋ณ๊ฒฝ๋ ์ ์์ผ๋ฉฐ, ๊ณ ๋๋ก ์ต์ ํ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฟผ๋ฆฌ, ํน์ UI ์๊ตฌ ์ฌํญ์ ์ง์ํ๋ ์๋ํฌ์ธํธ ๋ฑ์ ํฌํจํ ์ ์์ต๋๋ค.
์ด ๋ ๊ฐ์ง ๊ด์ฌ์ฌ๋ฅผ ๋ถ๋ฆฌํจ์ผ๋ก์จ, JSON API๋ ์์ ์ ์ด๊ณ ๊ท์น์ ์ด๋ฉฐ ์ ์ง ๊ด๋ฆฌ๊ฐ ์ ๊ฒ ํ์ํ๋ฉฐ, ํ์ดํผ๋ฏธ๋์ด API๋ ํผ๋์ค๋ฝ๊ณ ์ ๋ฌธํ๋๋ฉฐ ์ ์ฐํ ์ ์์ต๋๋ค. ๊ฐ๊ฐ์ ์๋ก ์ถฉ๋ํ์ง ์๊ณ ๋ฒ์ฑํ ์ ์๋ ์์ ๋ง์ ์ปจํธ๋กค๋ฌ ํ๊ฒฝ์ ๊ฐ๊ฒ ๋ฉ๋๋ค.
์ด๊ฒ์ด ์ ๊ฐ JSON๊ณผ ํ์ดํผ๋ฏธ๋์ด API๋ฅผ ๋ถ๋ฆฌํ์ฌ ๋ณ๋์ ์ปจํธ๋กค๋ฌ๋ก ๋ถ๋ฆฌํ๋ ๊ฒ์ ์ ํธํ๋ ์ด์ ์ด๋ฉฐ, HTTP ์ฝํ ์ธ ํ์์ ์ฌ์ฉํ์ฌ ๋ API๋ฅผ ์ฌ์ฌ์ฉํ๋ ค๋ ์๋๋ณด๋ค๋ ์ด ๋ฐฉ๋ฒ์ด ๋ ๋์ ์ ํ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.