[๋„คํŠธ์›Œํฌ] ๐Ÿ“š REST ์ดํ•ดํ•˜๊ธฐ

ํ—Œ์น˜ยท2022๋…„ 9์›” 5์ผ
2

๋„คํŠธ์›Œํฌ

๋ชฉ๋ก ๋ณด๊ธฐ
3/4
post-thumbnail

ํ•ด๋‹น ๊ธ€์€ CS ์Šคํ„ฐ๋””์—์„œ ๊ณต๋ถ€ํ•œ ๋‚ด์šฉ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

0. ๋“ค์–ด๊ฐ€๋ฉฐ

์ด๋ฒˆ์— CS์Šคํ„ฐ๋””์—์„œ REST ์ฃผ์ œ๋ฅผ ๋ฐœํ‘œํ•˜๊ธฐ๋กœ ๊ฒฐ์ •๋˜์—ˆ๋‹ค.

๋ฌด์—‡์ด ์ง„์งœ REST์ธ๊ฐ€์— ๋Œ€ํ•ด์„œ๋„ ๋งŽ์€ ๋…ผ์Ÿ์ด ์žˆ๊ณ , ์šฐ๋ฆฌ๊ฐ€ ํ”ํžˆ ์–˜๊ธฐํ•˜๋Š” REST์˜ ์กฐ๊ฑด์ธ CRUD, URL(URI) ๊ฐ€์ด๋“œ๋ผ์ธ์— ๋Œ€ํ•ด์„œ๋„ ๋ง์ด ๋งŽ๋‹ค.

๋ณด๋‹ค ๊ตฌ์ฒด์ ์œผ๋กœ ์•Œ๊ณ  ์‹ถ์–ด ๋ฌด์—‡์ด REST์ธ์ง€, ์ง„์งœ REST๋ฅผ ์ง€ํ‚ค๊ธฐ ์œ„ํ•ด ์–ด๋–ค ๊ณผ์ •์ด ํ•„์š”ํ•œ์ง€ ์ฐพ์•„๋ดค๋‹ค.

๐Ÿ™†โ€โ™€๏ธย ์ง„์งœ REST ๐Ÿ™†โ€โ™€๏ธ

๐Ÿ’ฌย ์ •์˜

REST

REST๋Š” Representational State Transfer(REST)์˜ ์•ฝ์ž๋กœ, API ์ž‘๋™ ๋ฐฉ์‹์— ๋Œ€ํ•œ ์กฐ๊ฑด์„ ๋ถ€๊ณผํ•˜๋Š” ์†Œํ”„ํŠธ์›จ์–ด ์•„ํ‚คํ…์ฒ˜์ด๋‹ค.

๋กœ์ด ํ•„๋”ฉ์ด ์ฐฝ์‹œํ–ˆ๋‹ค. ์ธํ„ฐ๋„ท๊ณผ ๊ฐ™์€ ๋ณต์žกํ•œ ๋„คํŠธ์›Œํฌ์—์„œ ํ†ต์‹ ์„ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์ง€์นจ์œผ๋กœ ๋งŒ๋“ค์–ด์กŒ๋‹ค.

REST API

API ๊ฐœ๋ฐœ์ž๋Š” ์—ฌ๋Ÿฌ ์•„ํ‚คํ…์ฒ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ API๋ฅผ ์„ค๊ณ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

REST ์•„ํ‚คํ…์ฒ˜ ์Šคํƒ€์ผ์„ ๋”ฐ๋ฅด๋Š” API๋ฅผ REST API๋ผ๊ณ  ํ•œ๋‹ค.

RESTful web service

REST ์•„ํ‚คํ…์ฒ˜๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ์›น ์„œ๋น„์Šค๋ฅผ RESTful ์›น ์„œ๋น„์Šค๋ผ๊ณ  ํ•œ๋‹ค.

ํ‘œํ˜„(Representation of Resource)

Client์™€ Server๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›๋Š” ํ˜•ํƒœ์ด๋‹ค.
JSON, XML, TEXT, RSS ๋“ฑ์ด ์žˆ๋‹ค.

๐Ÿ“„ย ํŠน์ง•

์š”์ƒˆ ๋Œ€๋‹ค์ˆ˜ API๋Š” 4๋ฒˆ ๋นผ๊ณ  ์ž˜ ์ง€์ผœ์ง„๋‹ค.

1. Server-Client(์„œ๋ฒ„-ํด๋ผ์ด์–ธํŠธ ๊ตฌ์กฐ)

์ž์›์ด ์žˆ๋Š” ์ชฝ์ด Server, ์ž์›์„ ์š”์ฒญํ•˜๋Š” ์ชฝ์ด Client์ด๋‹ค. ๋‘˜์€ ๋…๋ฆฝ์ ์ด๋‹ค.

2. Stateless(๋ฌด์ƒํƒœ)

์„œ๋ฒ„๋Š” ์ด์ „์˜ ๋ชจ๋“  ์š”์ฒญ๊ณผ ๋…๋ฆฝ์ ์œผ๋กœ ๋ชจ๋“  ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ์„ ์™„๋ฃŒํ•œ๋‹ค.

ํด๋ผ์ด์–ธํŠธ๋Š” ์ž„์˜์˜ ์ˆœ์„œ๋กœ ๋ฆฌ์†Œ์Šค๋ฅผ ์š”์ฒญํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋ชจ๋“  ์š”์ฒญ์€ ๋ฌด์ƒํƒœ์ด๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ์š”์ฒญ๊ณผ ๋ถ„๋ฆฌ๋œ๋‹ค.

3. Cacheable(์บ์‹œ ๊ฐ€๋Šฅ์„ฑ)

RESTful ์›น ์„œ๋น„์Šค๋Š” ์„œ๋ฒ„ ์‘๋‹ต ์‹œ๊ฐ„์„ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด ํด๋ผ์ด์–ธํŠธ ๋˜๋Š” ์ค‘๊ฐœ์ž์— ์ผ๋ถ€ ์‘๋‹ต์„ ์ €์žฅํ•˜๋Š” ํ”„๋กœ์„ธ์Šค์ธ ์บ์‹ฑ์„ ์ง€์›ํ•œ๋‹ค.

4. Uniform Interface(์ธํ„ฐํŽ˜์ด์Šค ์ผ๊ด€์„ฑ) : ํ•ต์‹ฌ

URI๋กœ ์ง€์ •ํ•œ Resource์— ๋Œ€ํ•œ ์กฐ์ž‘์„ ํ†ต์ผ๋˜๊ณ  ํ•œ์ •์ ์ธ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์ˆ˜ํ–‰ํ•œ๋‹ค.
HTTP ํ‘œ์ค€ ํ”„๋กœํ† ์ฝœ์— ๋”ฐ๋ฅด๋Š” ๋ชจ๋“  ํ”Œ๋žซํผ์—์„œ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
ํŠน์ • ์–ธ์–ด๋‚˜ ๊ธฐ์ˆ ์— ์ข…์†๋˜์ง€ ์•Š๋Š”๋‹ค.

5. Layered System(๊ณ„์ธตํ™”)

๊ณ„์ธตํ™”๋œ ์‹œ์Šคํ…œ ์•„ํ‚คํ…์ฒ˜์—์„œ ํด๋ผ์ด์–ธํŠธ๋Š” ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ์‚ฌ์ด์˜ ๋‹ค๋ฅธ ์Šน์ธ๋œ ์ค‘๊ฐœ์ž(๋ณด์•ˆ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ๋“ฑ)์—๊ฒŒ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

6. Code-On-Demand(์˜จ๋””๋งจ๋“œ ์ฝ”๋“œ) : optional

REST ์•„ํ‚คํ…์ฒ˜ ์Šคํƒ€์ผ์—์„œ ์„œ๋ฒ„๋Š” ์†Œํ”„ํŠธ์›จ์–ด ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์ฝ”๋“œ๋ฅผ ํด๋ผ์ด์–ธํŠธ์— ์ „์†กํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ ๊ธฐ๋Šฅ์„ ์ผ์‹œ์ ์œผ๋กœ ํ™•์žฅํ•˜๊ฑฐ๋‚˜ ์‚ฌ์šฉ์ž ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. โ†’ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ

๐Ÿ‘€ย 4๋ฒˆ Uniform Interface ์ œ์•ฝ์กฐ๊ฑด ํŒŒํ—ค์น˜๊ธฐ

1. identification of resources

๋ฆฌ์†Œ์Šค๋Š” uri๋ฅผ ํ†ตํ•ด ์‹๋ณ„๋œ๋‹ค.

2. manipulation of resources through representational

representation(ํ‘œํ˜„) ์ „์†ก์„ ํ†ตํ•ด ๋ฆฌ์†Œ์Šค๋ฅผ ์กฐ์ž‘ํ•ด์•ผ ํ•œ๋‹ค.

์ฆ‰ ๋ฆฌ์†Œ์Šค CRUD ์‹œ ๋ฉ”์„ธ์ง€์— ํ‘œํ˜„์„ ๋‹ด์•„์•ผ ํ•œ๋‹ค.

3. self-descriptive(ํ™•์žฅ ๊ฐ€๋Šฅํ•œ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜) : ๋ฌธ์ œ

๋ฉ”์„ธ์ง€๋Š” ์Šค์Šค๋กœ๋ฅผ ์„ค๋ช…ํ•ด์•ผ ํ•œ๋‹ค.

  • ๋ชจ๋“  ์š”์ฒญ ๋ฉ”์„ธ์ง€์—๋Š” ๋ชฉ์ ์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•ด Host๊ฐ€ ์ถ”๊ฐ€๋˜์–ด์•ผ ํ•œ๋‹ค.
  • ๋ชจ๋“  ์‘๋‹ต ๋ฉ”์„ธ์ง€์—๋Š” ๋ฐ”๋””๊ฐ’ ๋ฌธ๋ฒ• ํ•ด์„ ๋ฐฉ๋ฒ•์„ ์•Œ๋ ค์ฃผ๊ธฐ ์œ„ํ•ด Content-Type์ด ์ถ”๊ฐ€๋˜์–ด์•ผ ํ•œ๋‹ค.
    • ์ตœ๊ทผ ๋Œ€๋‹ค์ˆ˜ API์—์„  ์ž˜ ์ง€์ผœ์ง€์ง€ ์•Š๋Š”๋‹ค.(application/json๊นŒ์ง€๋งŒ ์ ๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Œ)

HTML์˜ ๊ฒฝ์šฐ self-descriptive ๋ฅผ ๋งŒ์กฑํ•˜์ง€๋งŒ, JSON์€ ๋งŒ์กฑํ•˜์ง€ ์•Š๋Š”๋‹ค.

4. HATEOAS(์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ƒํƒœ ์ „์ด์˜ late binding) : ๋ฌธ์ œ

HATEOAS : hypermedia as the engine of application state ์˜ ์ค„์ž„๋ง

์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ƒํƒœ๋Š” Hyperlink๋ฅผ ์ด์šฉํ•ด ์ „์ด๋˜์–ด์•ผ ํ•œ๋‹ค. ๋งํฌ๋Š” ๋™์ ์œผ๋กœ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

HTML์˜ ๊ฒฝ์šฐ HATEOAS๋ฅผ ๋งŒ์กฑํ•˜์ง€๋งŒ, JSON์€ ๋งŒ์กฑํ•˜์ง€ ์•Š๋Š”๋‹ค!

โค๏ธย REST์˜ ์ด์ 

1. ํ™•์žฅ์„ฑ

REST API๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ์‹œ์Šคํ…œ์€

  • REST๊ฐ€ ํด๋ผ์ด์–ธํŠธ-์„œ๋ฒ„ ์ƒํ˜ธ ์ž‘์šฉ์„ ์ตœ์ ํ™”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํšจ์œจ์ ์œผ๋กœ ํฌ๊ธฐ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋ฌด์ƒํƒœ๋Š” ์„œ๋ฒ„๊ฐ€ ๊ณผ๊ฑฐ ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ ์ •๋ณด๋ฅผ ์œ ์ง€ํ•  ํ•„์š”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋ฒ„ ๋กœ๋“œ๋ฅผ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.
  • ์ž˜ ๊ด€๋ฆฌ๋œ ์บ์‹ฑ์€ ์ผ๋ถ€ ํด๋ผ์ด์–ธํŠธ-์„œ๋ฒ„ ์ƒํ˜ธ ์ž‘์šฉ์„ ๋ถ€๋ถ„์ ์œผ๋กœ ๋˜๋Š” ์™„์ „ํžˆ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๋ชจ๋“  ๊ธฐ๋Šฅ์€ ์„ฑ๋Šฅ์„ ์ €ํ•˜์‹œํ‚ค๋Š” ํ†ต์‹  ๋ณ‘๋ชฉ ํ˜„์ƒ์„ ์ผ์œผํ‚ค์ง€ ์•Š์œผ๋ฉด์„œ ํ™•์žฅ์„ฑ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

2. ์œ ์—ฐ์„ฑ

RESTful ์›น ์„œ๋น„์Šค๋Š”

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

3. ๋…๋ฆฝ์„ฑ(๋…๋ฆฝ์  ์ง„ํ™”)

REST API๋Š” ์‚ฌ์šฉ๋˜๋Š” ๊ธฐ์ˆ ๊ณผ ๋…๋ฆฝ์ ์ž…๋‹ˆ๋‹ค.

API ์„ค๊ณ„์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๊ณ  ๋‹ค์–‘ํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋กœ ํด๋ผ์ด์–ธํŠธ ๋ฐ ์„œ๋ฒ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ชจ๋‘ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

๋˜ํ•œ ํ†ต์‹ ์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๊ณ  ์–‘์ชฝ(์„œ๋ฒ„, ํด๋ผ์ด์–ธํŠธ)์˜ ๊ธฐ๋ณธ ๊ธฐ์ˆ ์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

์ฆ‰, ์„œ๋ฒ„์˜ ๊ธฐ๋Šฅ์ด ๋ณ€๊ฒฝ๋˜์–ด๋„ ํด๋ผ์ด์–ธํŠธ๋ฅผ ์—…๋ฐ์ดํŠธํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค. ์ด๊ฒƒ์ด ๋กœ์ดํ•„๋”ฉ์ด REST๋ฅผ ๋งŒ๋“ค๊ฒŒ ๋œ ๊ณ„๊ธฐ์ด๋‹ค.

๐Ÿ™ƒย REST๋ฅผ ๋”ฐ๋ผ์•ผ ํ•˜๋Š”๊ฐ€?

์‹œ์Šคํ…œ ์ „์ฒด๋ฅผ ํ†ต์ œํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๊ฑฐ๋‚˜, ์ง„ํ™”์— ๊ด€์‹ฌ์ด ์—†๋‹ค๋ฉด, REST์— ๋Œ€ํ•ด ๋”ฐ์ง€๋Š๋ผ ์‹œ๊ฐ„์„ ๋‚ญ๋น„ํ•˜์ง€ ๋งˆ๋ผ - ๋กœ์ด ํ•„๋”ฉ

์ด ๊ฒฝ์šฐ ๋”ฐ๋ฅด์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

  1. ํด๋ผ์ด์–ธํŠธ-์„œ๋ฒ„ ๊ฐœ๋ฐœ์ž ์‚ฌ์ด์—์„œ ์˜์‚ฌ์†Œํ†ต์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
  2. ์ง์ ‘ ํด๋ผ์ด์–ธํŠธ, ์„œ๋ฒ„๋ฅผ ๋ชจ๋‘ ๊ตฌํ˜„ํ•œ๋‹ค.
  3. ์ง€์†์ ์ธ ์—…๋ฐ์ดํŠธโ†’๊ดœ์ฐฎ๋‹ค!

๋งŒ์•ฝ ์˜ค๋žœ ์‹œ๊ฐ„๋™์•ˆ ์ง„ํ™”ํ•˜๋Š”(๋ณ€๊ฒฝ ์—†์ด ๊ฐˆ ์ˆ˜ ์žˆ๋Š”) ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค๊ณ  ์‹ถ๋‹ค๋ฉด, RESTful API๋ฅผ ๋”ฐ๋ฅด๋Š” ๊ฒŒ ์ข‹๋‹ค.

๐Ÿ™€ย ์ง„์งœ RESTful API ๋งŒ๋“œ๋Š”๋ฒ•

Self-descriptive

Media type ์ •์˜

GET /todos HTTP/1.1
Host: example.org

HTTP/1.1 200 OK
Content-Type: application/vnd.todos+json

[
	{"id": 1, "title": "ํšŒ์‚ฌ ๊ฐ€๊ธฐ"},
	{"id": 2, "title": "์ง‘์— ๊ฐ€๊ธฐ"}
]
  1. ๋ฏธ๋””์–ด ํƒ€์ž…์„ ํ•˜๋‚˜ ์ •์˜
  2. ๋ฏธ๋””์–ด ํƒ€์ž… ๋ฌธ์„œ ์ž‘์„ฑ โ†’ "id", "title"์˜ ์˜๋ฏธ ์ •์˜
  3. IANA์— ๋ฏธ๋””์–ด ํƒ€์ž…์„ ๋“ฑ๋ก. ์ด๋•Œ ๋งŒ๋“  ๋ฌธ์„œ๋ฅผ ๋ฏธ๋””์–ด ํƒ€์ž…์˜ ๋ช…์„ธ๋กœ ๋“ฑ๋ก
  4. ์ด์ œ ์ด ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋Š” ์‚ฌ๋žŒ์€ ๋ช…์„ธ๋ฅผ ์ฐพ์•„๊ฐˆ ์ˆ˜ ์žˆ์Œ โ†’ ๋ฉ”์„ธ์‹œ์ง€ ์˜๋ฏธ ์˜จ์ „ํžˆ ํ•ด์„ ๊ฐ€๋Šฅ
  5. Success

๋‹จ์  : ๋งค๋ฒˆ media type ์ •์˜

Profile ์ด์šฉ

GET /todos HTTP/1.1
Host: example.org

HTTP/1.1 200 OK
Content-Type: application/json
Link: <https://exmaple.org/docs/todos>; rel="profile"

[
	{"id": 1, "title": "ํšŒ์‚ฌ ๊ฐ€๊ธฐ"},
	{"id": 2, "title": "์ง‘์— ๊ฐ€๊ธฐ"}
]
  1. "id", "title" ์˜๋ฏธ ์ •์˜ํ•œ ๋ช…์„ธ ์ž‘์„ฑ
  2. Link ํ—ค๋”์— profile relation์œผ๋กœ ๋ช…์„ธ ๋งํฌ
  3. ์ด์ œ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋Š” ์‚ฌ๋žŒ์€ ๋ช…์„ธ๋ฅผ ์ฐพ์•„๊ฐˆ ์ˆ˜ ์žˆ์Œ โ†’ ์˜๋ฏธ ํ•ด์„ ๊ฐ€๋Šฅ
  4. Success

๋‹จ์ 

  • ํด๋ผ์ด์–ธํŠธ๊ฐ€ Link ํ—ค๋”(RFC5988)์™€ profile(RFC 6906)์„ ์ดํ•ดํ•ด์•ผํ•จ.
  • Content negotiation ๋ถˆ๊ฐ€

HATEOAS

data์— ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ํ•˜์ดํผ๋งํฌ ํ‘œํ˜„

GET /todos HTTP/1.1
Host: example.org

HTTP/1.1 200 OK
Content-Type: application/json
Link: <https://exmaple.org/docs/todos>; rel="profile"

[
	{
		"link": "https://exmplae.org/todos/1,
		"title": "ํšŒ์‚ฌ ๊ฐ€๊ธฐ"
	},
	{
		"link": "https://exmplae.org/todos/2,
		"title": "ํšŒ์‚ฌ ๊ฐ€๊ธฐ"
	},
]
GET /todos HTTP/1.1
Host: example.org

HTTP/1.1 200 OK
Content-Type: application/json
Link: <https://exmaple.org/docs/todos>; rel="profile"

{
	"links" : {
		"todo" : "https://example.org/todos/{id}"
	},
	"data": [{
		"id": 1,
		"title": "ํšŒ์‚ฌ ๊ฐ€๊ธฐ"
	}, {
		"id": 2,
		"title": "์ง‘์— ๊ฐ€๊ธฐ"
	}]
}

๋‹จ์  : ๋งํฌ๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ง์ ‘ ์ •์˜

JSON์œผ๋กœ ํ•˜์ดํผ๋งํฌ๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ •์˜ํ•œ ๋ช…์„ธ๋“ค์„ ํ™œ์šฉ

GET /todos HTTP/1.1
Host: example.org

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
Link: <https://exmaple.org/docs/todos>; rel="profile"

{
	"data": [{
		"type": "todo",
		"id": 1,
		"attributes": {"title": "ํšŒ์‚ฌ ๊ฐ€๊ธฐ"},
	"links" : { "self": "https://example.org/todos/1"
	},{
		"type": "todo",
		"id": 2,
		"attributes": {"title": "์ง‘์— ๊ฐ€๊ธฐ"},
	"links" : { "self": "https://example.org/todos/2"
	}]
}

๋‹จ์  : ๊ธฐ์กด API๋ฅผ ๋งŽ์ด ๊ณ ์ณ์•ผํ•œ๋‹ค. (์นจํˆฌ์ )

HTTP ํ—ค๋”๋กœ โ†’ Link, Location ๋“ฑ

POST /todos HTTP/1.1
Content-Type: application/json

{
		"title": "์ ์‹ฌ ์•ฝ์†"
}

HTTP/1.1 204 No Content
Location: /todos/1
Link: </todos/>, rel="collection"

data, ํ—ค๋” ๋ชจ๋‘ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹๋‹ค.

๐Ÿ–Šย ์ •๋ฆฌ(feat.๊ทธ๋Ÿฐ REST API๋กœ ๊ดœ์ฐฎ์€๊ฐ€)

  • ์˜ค๋Š˜๋‚  ๋Œ€๋ถ€๋ถ„ "REST API"๋Š” ์‚ฌ์‹ค REST๋ฅผ ๋”ฐ๋ฅด๊ณ  ์žˆ์ง€ ์•Š๋‹ค.
  • REST์˜ ์ œ์•ฝ ์กฐ๊ฑด ์ค‘ ํŠนํžˆย self-descriptive์™€ HATEOAS๋ฅผ ์ž˜ ๋งŒ์กฑํ•˜์ง€ ๋ชปํ•œ๋‹ค.
  • RESTย ๊ธด ์‹œ๊ฐ„์— ๊ฑธ์ณ(์ˆ˜์‹ญ๋…„) ์ง„ํ™”ํ•˜๋Š” ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์œ„ํ•œ ๊ฒƒ
  • REST๋ฅผ ๋”ฐ๋ฅผ ๊ฒƒ์ธ์ง€๋Š” API ์„ค๊ณ„ํ•˜๋Š” ์ด๋“ค์ด ์Šค์Šค๋กœ ํŒ๋‹จํ•˜์—ฌ ๊ฒฐ์ •
  • REST๋ฅผ ๋”ฐ๋ฅด๊ฒ ๋‹ค๋ฉดย Self-decriptive์™€ HATEOAS๋ฅผ ๋งŒ์กฑ์‹œ์ผœ์•ผํ•œ๋‹ค.
    • Self-decriptiv๋Š”ย custom media type, profile link relation์œผ๋กœ ๋งŒ์กฑ ๊ฐ€๋Šฅ
    • HATEOAS๋Š”ย HTTP ํ—ค๋”๋‚˜ ๋ณธ๋ฌธ์—ย ๋งํฌ๋ฅผ ๋‹ด์•„ ๋งŒ์กฑ ๊ฐ€๋Šฅ
  • REST๋ฅผ ๋”ฐ๋ฅด์ง€ ์•Š๊ฒ ๋‹ค๋ฉด, "REST๋ฅผ ๋งŒ์กฑํ•˜์ง€ ์•Š๋Š” REST API"๋ฅผ ๋ญ๋ผ๊ณ  ๋ถ€๋ฅผ์ง€ ๊ฒฐ์ •ํ•ด์•ผํ•  ๊ฒƒ์ด๋‹ค.
    • HTTP API๋ผ๊ณ  ๋ถ€๋ฅผ ์ˆ˜๋„ ์žˆ๊ณ 
    • ๊ทธ๋ƒฅ ์ด๋Œ€๋กœ REST API๋ผ๊ณ  ๋ถ€๋ฅผ ์ˆ˜๋„ โ†’ ๋กœ์ด๊ฐ€ ์‹ซ์–ดํ•จ

๐Ÿฅฐย REST? : RESTful API ๊ฐ€์ด๋“œ๋ผ์ธ (feat.๋งˆ์ดํฌ๋กœ์†Œํ”„ํŠธ)

์—ฌ๊ธฐ์„œ๋ถ€ํ„ด ๋กœ์ด ํ•„๋”ฉ์˜ RESTful API๊ฐ€ ์•„๋‹Œ,
์ด๋ฅผ ํ•ด์„ํ•œ ์‚ฌ๋žŒ๋“ค(์ •ํ™•ํžˆ๋Š”, ๋งˆ์ดํฌ๋กœ์†Œํ”„ํŠธ docs)์˜ RESTful API์ด๋‹ค!

๐Ÿคย RESTful API ์š”์ฒญ ๊ตฌ์„ฑ์š”์†Œ ๊ฐ€์ด๋“œ๋ผ์ธ

RESTful API์—๋Š” ๋‹ค์Œ ๋‘ ๊ตฌ์„ฑ์š”์†Œ๋ฅผ ํฌํ•จํ•˜๋Š” ์š”์ฒญ์ด ํ•„์š”ํ•˜๋‹ค.

1. ์ž์›(Resource) - URL

REST ์„œ๋น„์Šค์˜ ๊ฒฝ์šฐ ์„œ๋ฒ„๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ URL์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฆฌ์†Œ์Šค ์‹๋ณ„์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. URL์€ ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•œ๋‹ค.

2. ํ–‰์œ„ - Method

HTTP ๋ฉ”์„œ๋“œ๋Š” ๋ฆฌ์†Œ์Šค์— ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜๋Š” ์ž‘์—…์„ ์„œ๋ฒ„์— ์•Œ๋ ค์ค€๋‹ค.

GET(Read)

์„œ๋ฒ„์˜ ์ง€์ •๋œ URL์— ์žˆ๋Š” ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผํ•œ๋‹ค.

์ด๋•Œ API ์š”์ฒญ์— ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋„ฃ์–ด ์ „์†กํ•˜์—ฌ ์ „์†ก ์ „์— ๋ฐ์ดํ„ฐ๋ฅผ ํ•„ํ„ฐ๋งํ•  ์ˆ˜ ์žˆ๋‹ค.

POST(Create)

์„œ๋ฒ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•œ๋‹ค.

์—ฌ๊ธฐ์—๋Š” ์š”์ฒญ๊ณผ ํ•จ๊ป˜ ๋ฐ์ดํ„ฐ ํ‘œํ˜„์ด ํฌํ•จ๋œ๋‹ค.

PUT(Update)

์„œ๋ฒ„์˜ ๊ธฐ์กด ๋ฆฌ์†Œ์Šค๋ฅผ ์ „์ฒด ์—…๋ฐ์ดํŠธํ•œ๋‹ค.

PATCH(Update)

์„œ๋ฒ„์˜ ๊ธฐ์กด ๋ฆฌ์†Œ์Šค๋ฅผ ์ผ๋ถ€ ์—…๋ฐ์ดํŠธํ•œ๋‹ค.

DELETE(Delete)

๋ฆฌ์†Œ์Šค๋ฅผ ์ œ๊ฑฐํ•œ๋‹ค.

HTTP ํ—ค๋”

์š”์ฒญ ํ—ค๋”๋Š” ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๊ฐ„์— ๊ตํ™˜๋˜๋Š” ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์š”์ฒญ ํ—ค๋”๋Š” ์š”์ฒญ ๋ฐ ์‘๋‹ต์˜ ํ˜•์‹์„ ๋‚˜ํƒ€๋‚ด๊ณ  ์š”์ฒญ ์ƒํƒœ ๋“ฑ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ

REST API ์š”์ฒญ์—๋Š” POST, PUT ๋ฐ ๊ธฐํƒ€ HTTP ๋ฉ”์„œ๋“œ๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์ž‘๋™ํ•˜๊ธฐ ์œ„ํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ํฌํ•จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํŒŒ๋ผ๋ฏธํ„ฐ

RESTful API ์š”์ฒญ์—๋Š” ์ˆ˜ํ–‰ํ•ด์•ผ ํ•  ์ž‘์—…์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์ •๋ณด๋ฅผ ์„œ๋ฒ„์— ์ œ๊ณตํ•˜๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ํฌํ•จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ๋ช‡ ๊ฐ€์ง€ ํŒŒ๋ผ๋ฏธํ„ฐ ์œ ํ˜•์ž…๋‹ˆ๋‹ค.

  • URL ์„ธ๋ถ€์ •๋ณด๋ฅผ ์ง€์ •ํ•˜๋Š” ๊ฒฝ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ.
  • ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์ •๋ณด๋ฅผ ์š”์ฒญํ•˜๋Š” ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ.
  • ํด๋ผ์ด์–ธํŠธ๋ฅผ ๋น ๋ฅด๊ฒŒ ์ธ์ฆํ•˜๋Š” ์ฟ ํ‚ค ํŒŒ๋ผ๋ฏธํ„ฐ.

๐Ÿ”—ย URL ๊ฐ€์ด๋“œ๋ผ์ธ

์Šฌ๋ž˜์‹œ( / )๋กœ ๊ณ„์ธต ๊ด€๊ณ„๋ฅผ ํ‘œํ˜„ํ•œ๋‹ค. ์ด๋•Œ ๋งˆ์ง€๋ง‰์— โ€œ/โ€ย ํฌํ•จํ•˜์ง€ ์•Š๋Š”๋‹ค.

๐Ÿ‘ŽBAD

http://api.test.com/users/1/

๐Ÿ‘GOOD

http://api.test.com/users/1

_(underbar) ๋Œ€์‹  -(dash)๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

๐Ÿ‘ŽBAD

http://api.test.com/users/post_commnets

๐Ÿ‘GOOD

http://api.test.com/users/post-commnets

์†Œ๋ฌธ์ž๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

๐Ÿ‘ŽBAD

http://api.test.com/users/postCommnets

๐Ÿ‘GOOD

http://api.test.com/users/post-commnets

๋ช…์‚ฌ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

๐Ÿ‘ŽBAD

POST http://api.test.com/users/1/delete-post/1

๐Ÿ‘GOOD

DELETE http://api.test.com/users/1/posts/1

์ปจํŠธ๋กค ์ž์›์„ ์˜๋ฏธํ•˜๋Š” URL ์˜ˆ์™ธ์ ์œผ๋กœ ๋™์‚ฌ๋ฅผ ํ—ˆ์šฉํ•œ๋‹ค.

๐Ÿ‘ŽBAD

http://api.test.com/posts/duplicating

๐Ÿ‘GOOD

http://api.test.com/posts/duplicate

ํŒŒ์ผํ™•์žฅ์ž๋Š” URI์— ํฌํ•จํ•˜์ง€ ์•Š๋Š”๋‹ค.

๐Ÿ‘ŽBAD

http://api.test.com/posts/1/photo.jpg

๐Ÿ‘GOOD

http://api.test.com/posts/1/photo

๐Ÿ“šย ์ฐธ๊ณ ์ž๋ฃŒ

์ดํƒœ๋ฆฌ ํ”ผ์ž

Day1, 2-2. ๊ทธ๋Ÿฐ REST API๋กœ ๊ดœ์ฐฎ์€๊ฐ€

RESTful API๋ž€ ๋ฌด์—‡์ธ๊ฐ€? - RESTful API ์ดˆ๋ณด์ž ๊ฐ€์ด๋“œ - AWS

[10๋ถ„ ํ…Œ์ฝ”ํ†ก] ์ •์˜ REST API

ํ•œ๊ตญ ์ฝค๋น„๋„ค์ด์…˜ ํ”ผ์ž

[Network] REST๋ž€? REST API๋ž€? RESTful์ด๋ž€? - Heee's Development Blog

์›น API ๋””์ž์ธ ๋ชจ๋ฒ” ์‚ฌ๋ก€ - Azure Architecture Center

api-guidelines/Guidelines.md at master ยท microsoft/api-guidelines

[10๋ถ„ ํ…Œ์ฝ”ํ†ก] ๋ฏผ์ดˆ์˜ RESTful

profile
๐ŸŒฑ ํ•จ๊ป˜ ์ž๋ผ๋Š” ์ค‘์ž…๋‹ˆ๋‹ค ๐Ÿš€ rerub0831@gmail.com

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