Why I Tend Not To Use Content Negotiation

Carson Gross

์ €๋Š” ํ•˜์ดํผ๋ฏธ๋””์–ด 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์˜ ํฅ๋ฏธ๋กœ์šด ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.

#API์—์„œ ์ฝ˜ํ…์ธ  ํ˜‘์ƒ ์‚ฌ์šฉํ•˜๊ธฐ

์ œ๊ฐ€ ์•Œ๊ณ  ์žˆ๋Š” ํ•œ, 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๋กœ ๋Œ์•„๊ฐ€์„œ, ์šฐ๋ฆฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

์ด ๊ตฌ์กฐ๋Š” ๋‘ ๊ฐœ์˜ ๋‹ค๋ฅธ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์•”์‹œํ•˜๋ฉฐ, ์ €๋Š” ์ด๊ฒƒ์ด ์ข‹์€ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. JSON API ์ปจํŠธ๋กค๋Ÿฌ๋Š” JSON API์˜ ์š”๊ตฌ ์‚ฌํ•ญ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: ์†๋„ ์ œํ•œ, ์•ˆ์ •์„ฑ, ๊ทธ๋ฆฌ๊ณ  GraphQL๊ณผ ๊ฐ™์€ ํ‘œํ˜„๋ ฅ ์žˆ๋Š” ์ฟผ๋ฆฌ ๋ฉ”์ปค๋‹ˆ์ฆ˜.

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

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

์ด๊ฒƒ์ด ์ œ๊ฐ€ JSON๊ณผ ํ•˜์ดํผ๋ฏธ๋””์–ด API๋ฅผ ๋ถ„๋ฆฌํ•˜์—ฌ ๋ณ„๋„์˜ ์ปจํŠธ๋กค๋Ÿฌ๋กœ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•˜๋Š” ์ด์œ ์ด๋ฉฐ, HTTP ์ฝ˜ํ…์ธ  ํ˜‘์ƒ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‘ API๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋ ค๋Š” ์‹œ๋„๋ณด๋‹ค๋Š” ์ด ๋ฐฉ๋ฒ•์ด ๋” ๋‚˜์€ ์„ ํƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

</>