๊นจ์•Œ ๊ฐœ๋… ๐Ÿ“‘/๊ธฐํƒ€

REST API (REpresentational State Transfer Application Programming Interface)

interfacer_han 2024. 5. 26. 13:29

#1 ๋ฌด์—‡(What)์— ๋Œ€ํ•œ API์ธ๊ฐ€?

#1-1 ๊ฐœ์š”

REST(REpresentational State Transfer) ๋˜๋Š” RESTful API๋Š” ์„œ๋ฒ„์˜ ์ž์›(Resource)์„ ๋‘๊ณ , ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๊ฐ„์˜ ํ†ต์‹  ๋ฐฉ๋ฒ•์„ ๊ทœ์ •ํ•˜๋Š” API(Application Programming Interface)๋‹ค. ์ž์›์ด๋ž€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋‹ค. ๋ธ”๋กœ๊ทธ๋ฅผ ์˜ˆ๋กœ ๋“ค๋ฉด ๊ฒŒ์‹œ๊ธ€, ๋Œ“๊ธ€ ๋“ฑ์ด ์ž์›์ด๋‹ค.
 
์ด ์ž์›์€ ์„œ๋กœ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋Š” ๊ณ ์œ ํ•œ ์‹๋ณ„์ž(URI)๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. REST API์—์„œ๋Š” URI์— ์†ํ•˜๋Š” ํ•˜์œ„ ๋ฒ”์ฃผ์ธ URL์„ ์ž์›์˜ ์‹๋ณ„์ž๋กœ์„œ ์‚ฌ์šฉํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด URL์ด ๋ฐ”๋กœ ์šฐ๋ฆฌ๊ฐ€ ์ผ์ƒ ์ƒํ™œ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋‹จ์–ด์ธ ์ธํ„ฐ๋„ท ์ฃผ์†Œ๋‹ค.
 

#1-2 URL(Uniform Resource Locator)์˜ ๊ตฌ์กฐ

์ด๋ฏธ์ง€ ์ถœ์ฒ˜: https://medium.com/@abhirup.acharya009/uri-vs-urn-vs-url-key-distinctions-explained-dec8e02ebd18

URL์˜ ์ „์ฒด ๊ตฌ์กฐ๋Š” ์œ„์™€ ๊ฐ™๋‹ค.
 

#1-3 Scheme

http
https
ftp
ssl
...

ํ†ต์‹ ์„ ์œ„ํ•œ ์ฒด๊ณ„(Scheme)๋กœ, ํ”„๋กœํ† ์ฝœ์ด๋ผ๊ณ  ํ•œ๋‹ค.
 

#1-4 Host

www.naver.com
123.789.456.777
...

์„œ๋ฒ„์˜ ๋„๋ฉ”์ธ ์ด๋ฆ„์ด๋‚˜ IP ์ฃผ์†Œ๋ฅผ ์ง€์ •ํ•œ๋‹ค.
 

#1-5 Port (์ƒ๋žต ๊ฐ€๋Šฅ)

:123
:777
:80
:443
...

์„œ๋ฒ„์˜ ์–ด๋–ค ํฌํŠธ์™€ ํ†ต์‹ ํ•  ์ง€๋ฅผ ์ง€์ •ํ•œ๋‹ค. ์ƒ๋žต ์‹œ์—๋Š” ๊ธฐ๋ณธ ํฌํŠธ ๋ฒˆํ˜ธ๊ฐ€ ํ• ๋‹น๋˜๋Š”๋ฐ, HTTP์˜ ๊ธฐ๋ณธ ํฌํŠธ ๋ฒˆํ˜ธ๋Š” 80์ด๊ณ  HTTPS์˜ ๊ธฐ๋ณธ ํฌํŠธ ๋ฒˆํ˜ธ๋Š” 443์ด๋ผ๊ณ  ํ•œ๋‹ค.
 

#1-6 Path (์ƒ๋žต ๊ฐ€๋Šฅ)

/137
/posts
/posts/4
...

์ž์›์˜ ์œ„์น˜๋‹ค. ์—ฌ๋Ÿฌ ํด๋”์— ๊ฒน๊ฒนํžˆ ์‹ธ์—ฌ์žˆ๋Š” ํŒŒ์ผ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋ณธ ๊ฒŒ์‹œ๊ธ€ #2-1์˜ ์ด๋ฏธ์ง€ ํ•˜๋‹จ์— ์žˆ๋Š” ์ถœ์ฒ˜ ๋งํฌ์—์„œ๋Š” /@abhirup.acharya009/uri-vs-urn-vs-url-key-distinctions-explained-dec8e02ebd18๊ฐ€ Path๋‹ค.
 

#1-7 Query Parameters (์ƒ๋žต ๊ฐ€๋Šฅ)

?id=2
?grade=1&major=computer%20science
...

๋ถˆ๋Ÿฌ์˜ฌ ์ž์›์„ ์„ ๋ณ„ํ•˜๋Š”, ํ•„ํ„ฐ๋งํ•˜๋Š” ์ผ์ข…์˜ ์กฐ๊ฑด๋ฌธ์ด๋‹ค. ํด๋ผ์ด์–ธํŠธ๋Š” ์ž์‹ ์ด ํ•„์š”ํ•œ ์ •๋ณด๋งŒ์„ ์„œ๋ฒ„์— ์š”์ฒญํ•  ์ˆ˜ ์žˆ์–ด ์ข‹๊ณ , ์„œ๋ฒ„๋„ ๋ณด๋‚ด์ค„ ์ž์›์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ ˆ์•ฝํ•˜๋Š” ํšจ๊ณผ๊ฐ€ ์žˆ๊ธฐ์— ์ด๋“์ด๋‹ค.
 

#1-8 Fragment Identifier (์ƒ๋žต ๊ฐ€๋Šฅ)

#summary
#inherited-fields
...

์ž์›์˜ ํŠน์ • ๋ฌธ๋‹จ์„ ์˜๋ฏธํ•œ๋‹ค. Fragment Identifier๊ฐ€ ํฌํ•จ๋œ URL์„ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์—ด๋ฉด, ํ•ด๋‹น ๋ฌธ๋‹จ๊นŒ์ง€ ์Šคํฌ๋กค์ด ๋‚ด๋ ค๊ฐ„ ์ƒํƒœ๋กœ ์›น ํŽ˜์ด์ง€๊ฐ€ ์—ด๋ฆฐ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ด ๋งํฌ์™€ ์ด ๋งํฌ๋Š” Fragment Identifier๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅด์ง€๋งŒ, ๋‚˜๋จธ์ง€๋Š” ๋˜‘๊ฐ™์€ URL ๋งํฌ๋‹ค. ๊ทธ๋Ÿผ์—๋„ ๋ธŒ๋ผ์šฐ์ €๋กœ ์—ด์—ˆ์„ ๋•Œ ๋ณด์ด๋Š” ๋‚ด์šฉ์ด ๋‹ค๋ฅด๋‹ค.

#2 ์–ด๋–ป๊ฒŒ(How) ์ž์›์„ ์š”์ฒญ(Request)ํ•˜๋Š”๊ฐ€?

#2-1 CRUD์˜ ๊ตฌํ˜„

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๊ธฐ๋ณธ์ ์ธ ๋™์ž‘์€ Create, Read, Update, Delete๋กœ ์šฐ๋ฆฌ๋ง๋กœ ํ•˜๋ฉด ์ฐจ๋ก€๋Œ€๋กœ ๋ฐ์ดํ„ฐ ์ƒ์„ฑ, ์ฝ๊ธฐ, ๊ฐฑ์‹ , ์‚ญ์ œ๋‹ค. ์˜์–ด ์•ž ๊ธ€์ž๋ฅผ ํ•˜๋‚˜์”ฉ ๋”ฐ์„œ CRUD๋ผ๊ณ ๋„ ๋ถ€๋ฅธ๋‹ค. #1์—์„œ REST API๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅ๋œ ์ž์›์„ ๋‹ค๋ฃจ๋Š” API๋ผ๊ณ  ํ–ˆ๋‹ค. ๋”ฐ๋ผ์„œ REST API์—๋Š” CRUD์„ ๊ตฌํ˜„(์ƒ์†)ํ•˜๋Š” ๋™์ž‘์ด ์žˆ๋‹ค. Create๋ฅผ ๊ตฌํ˜„ํ•œ Post, Read๋ฅผ ๊ตฌํ˜„ํ•œ Get, Update๋ฅผ ๊ตฌํ˜„ํ•œ Patch ๋˜๋Š” Put, Delete๋ฅผ ๋˜‘๊ฐ™์€ ์ด๋ฆ„์œผ๋กœ ๊ตฌํ˜„ํ•œ Delete๊ฐ€ ๊ทธ๊ฒƒ์ด๋‹ค. ์ด Post, Get, Patch, Put, Delete๋ฅผ HTTP ๋ฉ”์†Œ๋“œ๋ผ๊ณ  ํ•˜๋ฉฐ, REST API๋Š” HTTP ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด ์ž์›์„ ์š”์ฒญํ•œ๋‹ค. ์ด๋ฆ„์—์„œ ์•Œ ์ˆ˜ ์žˆ๋“ฏ HTTP ๋ฉ”์†Œ๋“œ๋Š” HTTP ํ”„๋กœํ† ์ฝœ์˜ ์ผ๋ถ€๋‹ค.

 

์—ฌ๋‹ด์œผ๋กœ ์—ฌ๊ธฐ์„œ ์ฃผ์˜ํ•  ์ ์€, HTTP ํ”„๋กœํ† ์ฝœ์€ REST API์˜ ์ „์œ ๋ฌผ์ด ์•„๋‹ˆ๋ผ๋Š” ๊ฒƒ์ด๋‹ค. REST API๋Š” HTTP ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•˜๋Š” ์ˆ˜ ๋งŽ์€ API ์ค‘ ํ•˜๋‚˜์— ๋ถˆ๊ณผํ•˜๋‹ค.
 

#2-2 HTTP (Hypertext Transfer Protocol) ์š”์ฒญ์˜ ๊ตฌ์กฐ

[HTTP ๋ฉ”์†Œ๋“œ] [Path + Query Parameter + Fragment Identifier] [HTTP ๋ฒ„์ „]
Host: [Host + Port]
User-Agent: [ํด๋ผ์ด์–ธํŠธ์˜ ์†Œํ”„ํŠธ์›จ์–ด(์šด์˜์ฒด์ œ, ๋ธŒ๋ผ์šฐ์ € ๋“ฑ) ์ข…๋ฅ˜์™€ ๋ฒ„์ „ ๋ช…์‹œ]
Content-Type: [(Body๊ฐ€ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ๋งŒ) ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„๋กœ ๋ณด๋‚ด๋Š” ๋ฏธ๋””์–ด ํƒ€์ž…(์ฝ˜ํ…์ธ  ์œ ํ˜•) ๋ช…์‹œ]
Content-Length: [(Body๊ฐ€ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ๋งŒ) ๋ณธ๋ฌธ(Body)๋งŒ์˜ ๊ธธ์ด(๋ฐ”์ดํŠธ ๋‹จ์œ„)๋ฅผ ๋ช…์‹œ. Body๊ฐ€ ์—†๋‹ค๋ฉด 0์œผ๋กœ ๋‘๊ฑฐ๋‚˜ ์ƒ๋žต]
Accept: [(์ƒ๋žต ๊ฐ€๋Šฅ) ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ›๊ธฐ๋ฅผ ์›ํ•˜๋Š” ๋ฏธ๋””์–ด ํƒ€์ž…(์ฝ˜ํ…์ธ  ์œ ํ˜•) ๋ช…์‹œ]
Accept-Language: [(์ƒ๋žต ๊ฐ€๋Šฅ) ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์›ํ•˜๋Š” ์–ธ์–ด์˜ ์šฐ์„  ์ˆœ์œ„๋ฅผ ์ง€์ •]
Referer: [(์ƒ๋žต ๊ฐ€๋Šฅ) ์ด์ „ ํŽ˜์ด์ง€์˜ URL. ์‚ฌ์šฉ์ž๊ฐ€ ์–ด๋””์—์„œ ์™”๋Š”์ง€ ๋ช…์‹œ]
Cache-Control: [(์ƒ๋žต ๊ฐ€๋Šฅ) ์บ์‹œ ์‚ฌ์šฉ์— ๋Œ€ํ•œ ์„ค์ •]
Connection: [(์ƒ๋žต ๊ฐ€๋Šฅ) ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๊ฐ„์˜ ์—ฐ๊ฒฐ์„ ์œ ์ง€ํ•  ๊ฒƒ์ธ์ง€์— ๊ด€ํ•œ ๋‚ด์šฉ]

[Body (๋ณธ๋ฌธ)]

์ „์ฒด์ ์ธ ๋ฌธ๋ฒ•์€ ์œ„์™€ ๊ฐ™๋‹ค. HTTP Method๋Š” HTTP ํ”„๋กœํ† ์ฝœ์˜ Header๋งŒ ์“ฐ๋Š”๊ฐ€? ์•„๋‹ˆ๋ฉด Body๊นŒ์ง€ ์“ฐ๋Š”๊ฐ€?๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋‹ค. [Body]์˜ ์œ— ๋ถ€๋ถ„์ด ์ „๋ถ€ Header๋‹ค. Body๋Š” ์„œ๋ฒ„์— ์–ด๋–ค ์ •๋ณด๋ฅผ ๋ณด๋‚ด๊ธฐ ์œ„ํ•œ ๊ณต๊ฐ„์ด๋‹ค. ๊ธ€๊ณผ ์‚ฌ์ง„์ด ์ž”๋œฉ ์ฒจ๋ถ€๋œ ๊ฒŒ์‹œ๊ธ€์„ ์ธํ„ฐ๋„ท ๊ฒŒ์‹œํŒ์— ์ž‘์„ฑํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ์˜ˆ๋กœ ๋“ค ์ˆ˜ ์žˆ๋‹ค. Post, Patch, Put์ด Body๊นŒ์ง€ ์“ฐ๋Š”(ํ•„์š”๋กœ ํ•˜๋Š”) HTTP Method๋‹ค. ๋ฐ˜๋ฉด, Get๊ณผ Delete๋Š” ์ž์›์˜ ๋‹จ์ˆœ ์ฐธ์กฐ, ๋‹จ์ˆœ ์‚ญ์ œ์ด๊ธฐ ๋•Œ๋ฌธ์— Body๊ฐ€ ํ•„์š”์—†๋‹ค.
 
์•„๋ž˜๋Š” ๊ทธ ์˜ˆ์‹œ๋“ค์ด๋‹ค.
 

#2-3 Post

POST /api/users HTTP/1.1
Host: www.example.com
Content-Type: application/json
Content-Length: 63

{
  "name": "John Doe",
  "email": "john.doe@example.com"
}

http://www.example.com/api/users์— ์ƒˆ user๋ฅผ ์ถ”๊ฐ€(Create)ํ•˜๋Š” Post Request๋‹ค. ํฌํŠธ ๋ฒˆํ˜ธ๋Š” ์ƒ๋žต๋˜์—ˆ์œผ๋ฉฐ, ์ด ๊ฒฝ์šฐ ๊ธฐ๋ณธ๊ฐ’ ํฌํŠธ ๋ฒˆํ˜ธ๋กœ ์š”์ฒญ๋œ๋‹ค.
 

#2-4 Get

GET /api/resource?id=123 HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0
Accept: application/json
Accept-Language: en-US,en;q=0.9
Referer: https://www.google.com/
Cache-Control: max-age=0
Connection: keep-alive

www.example.com/api/resource?id=123์„ Get(=Read)ํ•˜๋Š” ์š”์ฒญ(request)์ด๋‹ค. ์ด ํด๋ผ์ด์–ธํŠธ๋Š” ํ•ด๋‹น ์ž์›์„ JSON ํ˜•์‹์œผ๋กœ ๋ฐ›๊ธฐ๋ฅผ ์›ํ•˜๊ณ  ์žˆ๋‹ค.
 

#2-5 Patch

PATCH /api/users/123 HTTP/1.1
Host: http://www.example.com
Content-Type: application/json
Content-Length: 40

{
  "email": "new.email@example.com"
}

Patch๋Š” ๋ถ€๋ถ„ ์ˆ˜์ •์ด๋‹ค. ๋”ฐ๋ผ์„œ, ์ˆ˜์ •์ด ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ์ƒˆ๋กœ ๋ณด๋‚ธ๋‹ค. ๋ณด๋‚ด์ง€ ์•Š์€ ๋ถ€๋ถ„์€ ๊ธฐ์กด์˜ ์ž์›์ด ๊ทธ๋Œ€๋กœ ์œ ์ง€๋œ๋‹ค.
 

#2-6 Put

PUT /api/users/123 HTTP/1.1
Host: www.example.com
Content-Type: application/json
Content-Length: 67

{
  "name": "John Smith",
  "email": "john.smith@example.com"
}

HTTP ๋ฉ”์†Œ๋“œ๋ฅผ ์ œ์™ธํ•˜๋ฉด Post์™€ ์™„์ „ํžˆ ๋˜‘๊ฐ™๋‹ค. ๋‹ค๋งŒ, Post๋Š” ์กด์žฌํ•˜์ง€ ์•Š๋Š” ์ž์›์„ ์ฒ˜์Œ์œผ๋กœ ๋งŒ๋“œ๋Š” ์š”์ฒญ์ด์ง€๋งŒ, Put์€ ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ์ž์›์— ๊ฐ€ํ•˜๋Š” ์š”์ฒญ์ด๋ผ๋Š” ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค. 
 

#2-7 Delete

DELETE /api/users/123 HTTP/1.1
Host: www.example.com

ํ•ด๋‹น Path์˜ ์ž์›์„ ์‚ญ์ œํ•œ๋‹ค.
 

#3 ์–ด๋–ป๊ฒŒ(How) ์ž์›์„ ์‘๋‹ต(Response)ํ•ด ์ฃผ๋Š”๊ฐ€?

ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์š”์ฒญ(Request)ํ–ˆ์œผ๋ฏ€๋กœ, ์ด์ œ๋Š” ์„œ๋ฒ„๊ฐ€ ์‘๋‹ต(Response)ํ•ด์ค„ ์ฐจ๋ก€๋‹ค.
 

#3-1 HTTP (Hypertext Transfer Protocol) ์‘๋‹ต์˜ ๊ตฌ์กฐ

[HTTP ๋ฒ„์ „] [์ƒํƒœ ์ฝ”๋“œ] [(์ƒ๋žต ๊ฐ€๋Šฅ) ์ƒํƒœ ๋ฉ”์‹œ์ง€]
Data: [์‘๋‹ต์ด ์ƒ์„ฑ๋œ ๋‚ ์งœ์™€ ์‹œ๊ฐ„]
Content-Type: [์‘๋‹ต์˜ ๋ฏธ๋””์–ด ํƒ€์ž…(์ฝ˜ํ…์ธ  ์œ ํ˜•) ๋ช…์‹œ]
Content-Length: [๋ณธ๋ฌธ(Body)๋งŒ์˜ ๊ธธ์ด(๋ฐ”์ดํŠธ ๋‹จ์œ„)๋ฅผ ๋ช…์‹œ]
Location: [(์ฃผ๋กœ ์ƒํƒœ์ฝ”๋“œ๊ฐ€ 3xx์ผ ๋•Œ) ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ „๋‹ฌํ•  ์ž์›์˜ ์œ„์น˜]
Server: [(์ƒ๋žต ๊ฐ€๋Šฅ) ์„œ๋ฒ„์˜ ์†Œํ”„ํŠธ์›จ์–ด(์šด์˜์ฒด์ œ, ๋ธŒ๋ผ์šฐ์ € ๋“ฑ) ์ข…๋ฅ˜์™€ ๋ฒ„์ „ ๋ช…์‹œ]
Cache-Control: [(์ƒ๋žต ๊ฐ€๋Šฅ) ์บ์‹œ ์‚ฌ์šฉ์— ๋Œ€ํ•œ ์„ค์ •]
Expires: [(์ƒ๋žต ๊ฐ€๋Šฅ) ์‘๋‹ต์˜ ์œ ํšจ๊ธฐ๊ฐ„์„ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์•Œ๋ ค์คŒ. ์œ ํšจ๊ธฐ๊ฐ„ ์ดํ›„์—๋Š” ํ•ด๋‹น ์‘๋‹ต์„ ๋‹ค์‹œ ์š”์ฒญํ•ด์•ผ ํ•จ]
Set-Cookie: [(์ƒ๋žต ๊ฐ€๋Šฅ) ์„œ๋ฒ„๊ฐ€ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ฟ ํ‚ค๋ฅผ ์„ค์ •ํ•˜๋„๋ก ์ง€์‹œํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ]

[Body (๋ณธ๋ฌธ)]

์ „์ฒด์ ์ธ ๋ฌธ๋ฒ•์€ ์œ„์™€ ๊ฐ™๋‹ค. ์ƒํƒœ ์ฝ”๋“œ๋Š” 3์ž๋ฆฌ ์ˆซ์ž๋กœ, ํฌ๊ฒŒ 5๊ฐ€์ง€์˜ ๋ฒ”์ฃผ๋กœ ๋‚˜๋ˆ ์ง„๋‹ค. ์ƒํƒœ์ฝ”๋“œ์˜ ๋ฐฑ์˜ ์ž๋ฆฌ ์ˆซ์ž๊ฐ€ 1์ธ ๊ฒฝ์šฐ ์ฆ‰ ์ƒํƒœ์ฝ”๋“œ๊ฐ€ 1XX์ธ ๊ฒฝ์šฐ๋Š” ์ •๋ณด, ์˜ˆ๋ฅผ ๋“ค์–ด ํด๋ผ์ด์–ธํŠธ์˜ ๋‚จ์€ ์š”์ฒญ์„ ๋” ๋ฐ›์„ ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ์ •๋ณด๋ฅผ ์•Œ๋ ค์ฃผ๋Š” ์‘๋‹ต์ด๋‹ค. ์ƒํƒœ์ฝ”๋“œ๊ฐ€ 2XX๋Š” ์š”์ฒญ์ด ์„ฑ๊ณต์ ์œผ๋กœ ์ ‘์ˆ˜๋˜์—ˆ์Œ์„ ์˜๋ฏธํ•œ๋‹ค. 3XX๋Š” ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์ด ์™„์„ฑ๋˜๊ธฐ ์œ„ํ•ด์„œ ๋ฆฌ๋‹ค์ด๋ ‰์…˜๋“ฑ์˜ ์ถ”๊ฐ€์ ์ธ ์กฐ์น˜๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ๋ฅผ ์˜๋ฏธํ•œ๋‹ค. 4XX๋Š” ํด๋ผ์ด์–ธํŠธ ์ธก์˜ ์˜ค๋ฅ˜๋กœ ์ธํ•ด ์š”์ฒญ์ด ์‹คํŒจํ–ˆ์Œ์„, 5XX๋Š” ์„œ๋ฒ„ ์ธก์˜ ์˜ค๋ฅ˜๋กœ ์š”์ฒญ์ด ์‹คํŒจ๋์Œ์„ ์˜๋ฏธํ•œ๋‹ค. (์ฐธ์กฐ: ์ „์ฒด ์‘๋‹ต ์ฝ”๋“œ์˜ ๋ฆฌ์ŠคํŠธ)
 
์•„๋ž˜๋Š” ๊ทธ ์˜ˆ์‹œ๋‹ค.
 

#3-2 ์ƒํƒœ ์ฝ”๋“œ 1XX

HTTP/1.1 100 Continue
Date: Tue, 01 Jan 2024 12:00:00 GMT
Server: Apache/2.4.38 (Ubuntu)
Content-Length: 0
Connection: keep-alive

ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์š”์ฒญ์— ๋‹ด๊ธด ๋ณธ๋ฌธ์ด ๋‹ค ์„œ๋ฒ„๋กœ ์˜ฌ ๋•Œ๊นŒ์ง€ ๊ณ„์†ํ•ด์„œ ๋ณด๋‚ด๋ผ๋Š” ์„œ๋ฒ„ ์ธก์˜ ์‘๋‹ต
 

#3-3 ์ƒํƒœ ์ฝ”๋“œ 2XX - ๋ณธ๋ฌธ(Body)์ด HTML ํ˜•์‹์ธ ์‘๋‹ต

HTTP/1.1 200 OK
Date: Tue, 01 Jan 2024 12:00:00 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 129

<!DOCTYPE html>
<html>
<head>
  <title>Example Page</title>
</head>
<body>
  <h1>Hello, world!</h1>
</body>
</html>

 

#3-4 ์ƒํƒœ ์ฝ”๋“œ 2XX - ๋ณธ๋ฌธ(Body)์ด JSON ํ˜•์‹์ธ ์‘๋‹ต

HTTP/1.1 200 OK
Date: Tue, 01 Jan 2024 12:00:00 GMT
Content-Type: application/json; charset=UTF-8
Content-Length: 61

{
  "name": "John",
  "age": 30,
  "city": "New York"
}

 

#3-5 ์ƒํƒœ ์ฝ”๋“œ 3XX

HTTP/1.1 301 Moved Permanently
Date: Tue, 01 Jan 2024 12:00:00 GMT
Server: Apache/2.4.38 (Ubuntu)
Location: https://www.example.com/new-page
Content-Length: 0
Connection: keep-alive

ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์š”์ฒญํ•œ ์ž์›์ด ์ƒˆ ์œ„์น˜๋กœ ์ด๋™๋˜์—ˆ์Œ์„ ๋‚˜ํƒ€๋‚ด๋Š” ์‘๋‹ต์ด๋‹ค. ํด๋ผ์ด์–ธํŠธ๋Š” Location์— ๋ช…์‹œ๋œ ์ž์›์œผ๋กœ ์ž๋™์œผ๋กœ ์ด๋™๋œ๋‹ค.
 

#3-6 ์ƒํƒœ ์ฝ”๋“œ 4XX

HTTP/1.1 404 Not Found
Date: Tue, 01 Jan 2024 12:00:00 GMT
Content-Type: text/plain; charset=UTF-8
Content-Length: 13

404 Not Found

ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์š”์ฒญํ•œ ์ž์›์ด ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์˜ ์‘๋‹ต.
 

#3-7 ์ƒํƒœ ์ฝ”๋“œ 5XX

HTTP/1.1 500 Internal Server Error
Date: Tue, 01 Jan 2024 12:00:00 GMT
Content-Type: text/plain; charset=UTF-8
Content-Length: 18

500 Internal Error

์„œ๋ฒ„ ๋‚ด๋ถ€ ์˜ค๋ฅ˜.
 

#4 REST API๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ์„œ๋ฒ„๊ฐ€ ์ง€์ผœ์•ผํ•  ๊ทœ์น™

#4-1 Stateless

ํด๋ผ์ด์–ธํŠธ: "์„œ๋ฒ„์•ผ, A ์•Œ๋ ค์ค˜."
์„œ๋ฒ„: "๋„ค."
...
ํด๋ผ์ด์–ธํŠธ: "์„œ๋ฒ„์•ผ, A ์•Œ๋ ค์ค˜."
์„œ๋ฒ„: "์•„๊นŒ ์ „์— ์ด๋ฏธ ๋‚ด๊ฐ€ ์ •๋ณด๋ฅผ ์•Œ๋ ค์คฌ๋˜ ํด๋ผ์ด์–ธํŠธ์ž–์•„? ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ ์•ˆ ๋ผ."
ํด๋ผ์ด์–ธํŠธ: "์ด ์„œ๋ฒ„ Stateless ์•ˆ ์ง€ํ‚ค๋„ค..."

์„œ๋ฒ„๋Š” ํด๋ผ์ด์–ธํŠธ์— ๋Œ€ํ•ด ์•„๋ฌด๊ฒƒ๋„ ๊ธฐ์–ตํ•˜์ง€ ์•Š์•„์•ผ ํ•œ๋‹ค.
 

#4-2 Idempotent (๋ฉฑ๋“ฑ์„ฑ)

ํด๋ผ์ด์–ธํŠธ: "(์ธํ„ฐ๋„ท ์‡ผํ•‘ ์ค‘) ์ปดํ“จํ„ฐ๊ฐ€ ๋ ‰์ด ์‹ฌํ•ด์„œ, ์‹ค์ˆ˜๋กœ ์ฃผ๋ฌธ ์™„๋ฃŒ ๋ฒ„ํŠผ์ด 5๋ฒˆ ํด๋ฆญ๋ผ๋ฒ„๋ ธ๋„ค."
์„œ๋ฒ„: "์š”์ฒญํ•˜์‹  5๊ฑด์˜ ์ฃผ๋ฌธ์ด ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค."
ํด๋ผ์ด์–ธํŠธ: "์ด ์„œ๋ฒ„ ๋ฉฑ๋“ฑ์„ฑ ์•ˆ ์ง€ํ‚ค๋„ค..."

๋ฉฑ๋“ฑ(ๅ†ช็ญ‰): ์—ฐ์‚ฐ์„ ์—ฌ๋Ÿฌ ๋ฒˆ ์ ์šฉํ•˜๋”๋ผ๋„ ๊ฒฐ๊ด๊ฐ’์ด ๋‹ฌ๋ผ์ง€์ง€ ์•Š๋Š” ์ผ.
 

#4-3 Cacheability

ํด๋ผ์ด์–ธํŠธ: "(๋™์˜์ƒ ์‚ฌ์ดํŠธ ์ด์šฉ ์ค‘) ์ด ๋ฎค์ง ๋น„๋””์˜ค ๋ฐ˜๋ณต ์žฌ์ƒ ์„ค์ •ํ•ด์„œ ํ‹€์–ด๋†”์•ผ์ง€."
...
ํด๋ผ์ด์–ธํŠธ: "๋ฒŒ์จ ํœด๋Œ€ํฐ ๋ฐ์ดํ„ฐ๊ฐ€ ๋‹ค ์†Œ์ง„๋๋„ค ์™œ์ง€?"
ํด๋ผ์ด์–ธํŠธ: "์•„... ์ด ์‚ฌ์ดํŠธ๊ฐ€ ๋™์˜์ƒ์„ ์บ์‹œ์— ์ €์žฅ์•Š๊ณ , ๋ฐ˜๋ณต ์žฌ์ƒ๋  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ  ์žˆ์—ˆ๊ตฌ๋‚˜."
ํด๋ผ์ด์–ธํŠธ: "์ด ์„œ๋ฒ„ Cacheability ์•ˆ ์ง€ํ‚ค๋„ค..."

ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„๋Š” ์„œ๋กœ์— ๋Œ€ํ•ด '๊ธฐ์–ต'ํ•˜์ง€ ์•Š์•„์•ผ ํ•˜์ง€๋งŒ, ๊ฐ๊ฐ ์–ด๋–ค ์‘๋‹ต์„ ๋ณด๋‚ด๊ฑฐ๋‚˜ ๋ฐ›์•˜๋Š”์ง€๋Š” ๊ธฐ์–ตํ•ด๋‘๋Š” ๊ฒŒ ์ข‹๋‹ค. ํด๋ผ์ด์–ธํŠธ ์ธก์˜ Cacheability๋ฅผ ๋‹ค๋ฃฌ ์œ„ ์˜ˆ์‹œ์™€ ๋ฐ˜๋Œ€ ๋ฐฉํ–ฅ์œผ๋กœ, ์„œ๋ฒ„ ์ธก์˜ Cacheability๋„ ๊ทธ๋ ‡๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋Œ€๋ถ€๋ถ„์˜ ํด๋ผ์ด์–ธํŠธ๋“ค์ด ์š”์ฒญํ•˜๋Š” ์ธ๊ธฐ ์ž์›์ด ์žˆ๋‹ค๋ฉด, ์„œ๋ฒ„์˜ ์บ์‹œ ์ €์žฅ์†Œ์— ๋‘ฌ์„œ ์žฌ๋นจ๋ฆฌ ์‘๋‹ตํ•ด์ค„ ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค.
 

#5 ์š”์•ฝ

REST API๋Š” ์„œ๋ฒ„์˜ ์ž์›(Resource)์„ ๋‘๊ณ , ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๊ฐ„์˜ ํ†ต์‹  ๋ฐฉ๋ฒ•์„ ๊ทœ์ •ํ•˜๋Š” API๋‹ค.
 

#6 ์ด ๊ฐœ๋…์ด ์‚ฌ์šฉ๋œ ๊ธ€

-