Post

[Network] REST, RESTful API๋ž€?

[Network] REST, RESTful API๋ž€?

๐Ÿ“Œ RESTful API๋ž€?

image.png

REST(Representational State Transfer ๋Š” ์ž์›์„ ์ด๋ฆ„์œผ๋กœ ๊ตฌ๋ถ„ํ•˜์—ฌ ์ž์›์˜ ์ƒํƒœ๋ฅผ ์ฃผ๊ณ ๋ฐ›๋Š” ์†Œํ”„ํŠธ์›จ์–ด ์•„ํ‚คํ…์ฒ˜ ์Šคํƒ€์ผ์ด๋‹ค.

REST๋Š” ์›น์—์„œ ๋‹ค๋ฃจ๋Š” ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ์ž์›์œผ๋กœ ๋ณด๋ฉฐ, ๊ฐ ์ž์›์€ ๊ณ ์œ ํ•œ URI๋กœ ์‹๋ณ„ํ•œ๋‹ค. ์ž์›์„ ์ฃผ๊ณ ๋ฐ›์„ ๋•Œ, ์ž์› ๊ทธ ์ž์ฒด๊ฐ€ ์•„๋‹ˆ๋ผ JSON, XML๊ณผ ๊ฐ™์€ ์ž์›์˜ โ€˜ํ‘œํ˜„โ€™์„ ์ฃผ๊ณ ๋ฐ›๋Š”๋‹ค. ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„๋Š” HTTP ์š”์ฒญ ๋ฐ ์‘๋‹ต์„ ํ†ตํ•ด ์ž์›์˜ ์ƒํƒœ๋ฅผ ์ฃผ๊ณ ๋ฐ›๋Š”๋‹ค. ์„œ๋ฒ„๋Š” ํด๋ผ์ด์–ธํŠธ์˜ ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค.

RESTful API ๋ž€ REST ์›์น™์„ ์ž˜ ์ง€์ผœ์„œ ๊ตฌํ˜„๋œ ์‹œ์Šคํ…œ ๋˜๋Š” API๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

๐Ÿ“Œ REST์˜ ๊ตฌ์„ฑ ์š”์†Œ

์ž์›(Resource)

์ž์›์€ ์„œ๋ฒ„๊ฐ€ ๊ด€๋ฆฌํ•˜๋Š” ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ์˜๋ฏธํ•˜๋ฉฐ ๊ฐ ์ž์›์€ ๊ณ ์œ ํ•œ URI๋กœ ์‹๋ณ„๋œ๋‹ค. ํด๋ผ์ด์–ธํŠธ๋Š” URI๋ฅผ ํ†ตํ•ด ์ž์›์„ ์ง€์ •ํ•˜๊ณ , ์„œ๋ฒ„์— ํ•ด๋‹น ์ž์›์˜ ์ƒํƒœ์— ๋Œ€ํ•œ CRUD ์ž‘์—…์„ ์š”์ฒญํ•œ๋‹ค.

ํ–‰์œ„(Verb, HTTP Method)

์ž์›์— ๋Œ€ํ•ด ์–ด๋–ค ๋™์ž‘์„ ์ˆ˜ํ–‰ํ• ์ง€ ํ‘œํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์–ด๋–ค ๋™์ž‘์„ ์›ํ•˜๋Š”์ง€ ์„œ๋ฒ„์— ์ „๋‹ฌํ•˜๊ณ  ์„œ๋ฒ„๋Š” ํ•ด๋‹น ๋ฉ”์„œ๋“œ์— ๋งž๋Š” ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

GET : ์ž์› ์กฐํšŒ

POST : ์ž์› ์ƒ์„ฑ

PUT : ์ž์› ์ „์ฒด ์ˆ˜์ •

PATCH : ์ž์› ์ผ๋ถ€ ์ˆ˜์ •

DELETE : ์ž์› ์‚ญ์ œ

ํ‘œํ˜„(Representation)

์ž์›์˜ ์‹ค์ œ ๋ฐ์ดํ„ฐ๊ฐ€ ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๊ฐ„ ์ฃผ๊ณ ๋ฐ›๋Š” ํ˜•ํƒœ๋ฅผ ์˜๋ฏธํ•œ๋‹ค. JSON, XML, HTML ๋“ฑ์˜ ํ˜•ํƒœ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“Œ REST์˜ ํŠน์ง•

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

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

๋ฌด์ƒํƒœ์„ฑ(Stateless)

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

์บ์‹œ ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ(Cacheable)

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

๊ณ„์ธตํ™” ์‹œ์Šคํ…œ(Layered System)

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

์ผ๊ด€๋œ ์ธํ„ฐํŽ˜์ด์Šค(Uniform Interface)

REST๋Š” ์ผ๊ด€๋˜๊ณ  ์ œํ•œ์ ์ธ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ๋ชจ๋“  ์ž์›์€ URI๋กœ ์‹๋ณ„ ๊ฐ€๋Šฅํ•˜๋ฉฐ HTTP Method๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์กฐ์ž‘ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ๋‹ค์–‘ํ•œ ํด๋ผ์ด์–ธํŠธ์—์„œ ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ API๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“Œ ์„ค๊ณ„ ๋ฐ ๊ตฌํ˜„

์ž์› ์ค‘์‹ฌ URI

  • ๋™์‚ฌ๊ฐ€ ์•„๋‹Œ ๋ช…์‚ฌ๋กœ ์ž‘์„ฑํ•œ๋‹ค.
    • ex) /users , posts/15
  • ์ž์›์˜ ์ง‘ํ•ฉ์€ ๋ณต์ˆ˜ํ˜• ๋ช…์‚ฌ๋กœ ์ž‘์„ฑํ•œ๋‹ค.
    • ex) /students
  • ํ•ญ์ƒ ์†Œ๋ฌธ์ž๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
    • ex) /users (O), /Users (X)
  • ์—ฌ๋Ÿฌ ๋‹จ์–ด๋กœ ๊ตฌ์„ฑ๋œ ๊ฒฝ์šฐ ํ•˜์ดํ”ˆ(-)์„ ์‚ฌ์šฉํ•œ๋‹ค.
    • ex) /user-groups
  • ์Šฌ๋ž˜์‹œ(/)๋ฅผ ํ†ตํ•ด ๊ณ„์ธต ๊ด€๊ณ„๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.
    • ex) /users/3/posts (3๋ฒˆ ์‚ฌ์šฉ์ž์˜ ๊ฒŒ์‹œ๊ธ€)
  • ๋งˆ์ง€๋ง‰์— ์Šฌ๋ž˜์‹œ๋ฅผ ๋ถ™์ด์ง€ ์•Š๋Š”๋‹ค.
    • ex) /users (O), /users/ (X)

HTTP Method

  • ๋ชฉ์ ์— ๋งž๊ฒŒ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.
    • ex) GET /users/1 (1๋ฒˆ ์‚ฌ์šฉ์ž ์ •๋ณด ์กฐํšŒ)
  • URI์— ๋™์ž‘์ด๋‚˜ CRUD ํ•จ์ˆ˜๋ช…์„ ํฌํ•จํ•˜๋ฉด ์•ˆ ๋œ๋‹ค.
    • ex) DELETE /users/1 (O), DELETE /users/delete/1 (X)

HTTP ์ƒํƒœ ์ฝ”๋“œ

  • ์ ์ ˆํ•œ ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ๋ฆฌํ„ดํ•˜๋„๋ก ํ•ด์•ผ ํ•œ๋‹ค.
    • ex) 200 OK (์š”์ฒญ ์„ฑ๊ณต), 500 Unternal Server Error (์„œ๋ฒ„ ์˜ค๋ฅ˜)

๐Ÿ“Œ ํ•œ๊ณ„ ๋ฐ ์ฃผ์˜์ 

์˜ค๋ฒ„ํŽ˜์นญ(Over-fetching), ์–ธ๋”ํŽ˜์นญ(Under-fetching)

Over-fetching ์€ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์‹ค์ œ๋กœ ํ•„์š”ํ•˜์ง€ ์•Š๋Š” ๋ฐ์ดํ„ฐ๊นŒ์ง€ ๋ฐ›๋Š” ํ˜„์ƒ์„ ๋งํ•œ๋‹ค. REST API๋Š” ์—”๋“œํฌ์ธํŠธ๋ณ„๋กœ ๊ณ ์ •๋œ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ๋ฆฌํ„ดํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์‚ฌ์šฉ์ž ์ •๋ณด์—์„œ id ๋งŒ ํ•„์š”ํ•˜๋‚˜ createAt ๊ณผ ๊ฐ™์€ ๋ถˆํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๊นŒ์ง€ ์ „๋‹ฌ๋  ์ˆ˜ ์žˆ๋‹ค.

Under-fetching ์€ ํ•œ ๋ฒˆ์˜ ์š”์ฒญ์œผ๋กœ ๋ชจ๋“  ์ •๋ณด๋ฅผ ์–ป์ง€ ๋ชปํ•˜์—ฌ ์—ฌ๋Ÿฌ ๋ฒˆ์˜ ์ถ”๊ฐ€ ์š”์ฒญ์ด ํ•„์š”ํ•œ ํ˜„์ƒ์„ ๋งํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์‚ฌ์šฉ์ž์˜ ์ •๋ณด์™€ ์ž‘์„ฑํ•œ ๊ฒŒ์‹œ๊ธ€ ์ •๋ณด๋ฅผ ํ•œ ๋ฒˆ์— ๋ฐ›์ง€ ๋ชปํ•˜๊ณ  ์—ฌ๋Ÿฌ ์—”๋“œํฌ์ธํŠธ๋ฅผ ํ˜ธ์ถœํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค.

์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ํ•œ๊ณ„

REST API๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ•„์š”๋กœ ํ•  ๋•Œ ์„œ๋ฒ„์— ์š”์ฒญ์„ ๋ณด๋‚ด๊ธฐ ๋•Œ๋ฌธ์— ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•˜๋Š” ์ƒํ™ฉ์—์„œ๋Š” ๋น„ํšจ์œจ์ ์ด๋‹ค. ์ด ๊ฒฝ์šฐ, WebSocket๊ณผ ๊ฐ™์€ API๊ฐ€ ๋” ์ ํ•ฉํ•˜๋‹ค.

๋ฌด์ƒํƒœ์„ฑ์˜ ํ•œ๊ณ„

REST๋Š” Stateless๋ฅผ ์›์น™์œผ๋กœ ํ•˜๋ฏ€๋กœ ๋งค ์š”์ฒญ๋งˆ๋‹ค ์ธ์ฆ ์ •๋ณด์™€ ๊ฐ™์€ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ๋‘ ํฌํ•จํ•ด์•ผ ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ๋ณต์žกํ•œ ์ƒํƒœ ๊ด€๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ ์„œ๋น„์Šค์˜ ๊ฒฝ์šฐ ์ ํ•ฉํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“Œ ์ฐธ๊ณ 

https://peonyf.tistory.com/entry/Network-REST-API

https://dev-coco.tistory.com/97

This post is licensed under CC BY 4.0 by the author.