๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ’ป CS

HTTP ์ •๋ฆฌ ๋ฐ ์งˆ๋ฌธ ๋ฆฌ์ŠคํŠธ (feat.RESTful)

by dev.py 2025. 3. 22.

1. HTTP ์ •๋ฆฌ

๐Ÿ“Œ ์ฃผ์š” ์ƒํƒœ ์ฝ”๋“œ ์š”์•ฝ ์ •๋ฆฌํ‘œ 

์ƒํƒœ ์ฝ”๋“œ  ์˜๋ฏธ ์‚ฌ์šฉ์˜ˆ์‹œ
200 OK ์„ฑ๊ณต ์ผ๋ฐ˜์ ์ธ ์š”์ฒญ ์„ฑ๊ณต
201 Created ๋ฆฌ์†Œ์Šค ์ƒ์„ฑ๋จ POST๋กœ ์ƒˆ๋กœ์šด ๋ฆฌ์†Œ์Šค ์ƒ์„ฑ
204 No Content ์„ฑ๊ณตํ–ˆ์ง€๋งŒ ์‘๋‹ต ๋ณธ๋ฌธ ์—†์Œ DELETE, PATCH ๋“ฑ ํ›„์— ๋ณธ๋ฌธ ๋ถˆํ•„์š”ํ•  ๋•Œ
400 Bad Request ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ ์˜ค๋ฅ˜ ์ž˜๋ชป๋œ ํŒŒ๋ผ๋ฏธํ„ฐ, JSON ํŒŒ์‹ฑ ์‹คํŒจ
401 Unauthorized ์ธ์ฆ ์‹คํŒจ ๋กœ๊ทธ์ธ/ํ† ํฐ ์—†์Œ, ๋งŒ๋ฃŒ
403 Forbidden ๊ถŒํ•œ ์—†์Œ ๋กœ๊ทธ์ธ์€ ๋์ง€๋งŒ ๊ถŒํ•œ ์—†์Œ
404 Not Found ๋ฆฌ์†Œ์Šค ์—†์Œ ๊ฒฝ๋กœ ๋˜๋Š” ๋ฆฌ์†Œ์Šค ์กด์žฌํ•˜์ง€ ์•Š์Œ
405 Method Not Allowed ๋ฉ”์„œ๋“œ ํ—ˆ์šฉ ์•ˆ๋จ GET๋งŒ ์ง€์›ํ•˜๋Š” API์— POST ์š”์ฒญ ๋“ฑ
409 Conflict ๋ฆฌ์†Œ์Šค ์ถฉ๋Œ ์ค‘๋ณต ์š”์ฒญ, ๋ฒ„์ „ ์ถฉ๋Œ ๋“ฑ
429 Too Many Requests ๋„ˆ๋ฌด ๋งŽ์€ ์š”์ฒญ Rate limit ์ดˆ๊ณผ
500 Internal Server Error ์„œ๋ฒ„ ๋‚ด๋ถ€ ์˜ค๋ฅ˜ ์˜ˆ์™ธ ๋ฐœ์ƒ, ๋กœ์ง ์—๋Ÿฌ ๋“ฑ
502 Bad Gateway ๊ฒŒ์ดํŠธ์›จ์ด ์˜ค๋ฅ˜ ํ”„๋ก์‹œ/๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ๊ฐ€ ๋’ค ์„œ๋ฒ„์—์„œ ์ž˜๋ชป๋œ ์‘๋‹ต ๋ฐ›์Œ
503 Service Unavailable ์„œ๋ฒ„ ๊ณผ๋ถ€ํ•˜ or ์ ๊ฒ€ ์ค‘ ์ผ์‹œ์  ์„œ๋น„์Šค ๋ถˆ๊ฐ€
504 Gateway Timeout ๋’ค์ชฝ ์„œ๋ฒ„ ์‘๋‹ต ์ง€์—ฐ ํ”„๋ก์‹œ๊ฐ€ ๋ฐฑ์—”๋“œ๋กœ๋ถ€ํ„ฐ ์‘๋‹ต ๋ชป ๋ฐ›์Œ

 

๐Ÿ“Œ ์ž์ฃผ ๋น„๊ต๋˜๋Š” ์ƒํƒœ ์ฝ”๋“œ ์ฐจ์ด

ํ•ญ๋ชฉ  ์˜๋ฏธ / ์šฉ๋„
401 vs 403 401: ์ธ์ฆ์ด ์•„์˜ˆ ์•ˆ ๋จ (ex. ํ† ํฐ ์—†์Œ)
403: ์ธ์ฆ์€ ๋์ง€๋งŒ ๊ถŒํ•œ ์—†์Œ
200 vs 204 200: ์‘๋‹ต ๋ณธ๋ฌธ ์žˆ์Œ
204: ์‘๋‹ต ๋ณธ๋ฌธ ์—†์Œ
404 vs 405 404: URL ์ž์ฒด ์—†์Œ
405: URL์€ ์žˆ์ง€๋งŒ HTTP ๋ฉ”์„œ๋“œ๊ฐ€ ์ž˜๋ชป๋จ
301 vs 302 301: ์˜๊ตฌ ์ด๋™ (๋ธŒ๋ผ์šฐ์ € ์บ์‹œ)
302: ์ž„์‹œ ์ด๋™
304 vs 200 304: ์บ์‹œ๋œ ์‘๋‹ต ์žฌ์‚ฌ์šฉ (๋ณธ๋ฌธ ์—†์Œ)
200: ๋ฆฌ์†Œ์Šค ์ „์†ก

 

๐Ÿ“Œ HTTP ๋ฉ”์„œ๋“œ ์š”์•ฝ ์ •๋ฆฌ

๋ฉ”์„œ๋“œ ์„ค๋ช… ๋ฉฑ๋“ฑ์„ฑ ์บ์‹ฑ
GET ๋ฐ์ดํ„ฐ ์กฐํšŒ โœ… ์žˆ์Œ โœ… ๊ฐ€๋Šฅ
POST ๋ฐ์ดํ„ฐ ์ƒ์„ฑ โŒ ์—†์Œ โŒ ์—†์Œ
PUT ๋ฆฌ์†Œ์Šค ์ „์ฒด ์ˆ˜์ • โœ… ์žˆ์Œ โŒ ์—†์Œ
PATCH ๋ฆฌ์†Œ์Šค ๋ถ€๋ถ„ ์ˆ˜์ • โœ… ์žˆ์Œ โŒ ์—†์Œ
DELETE ๋ฆฌ์†Œ์Šค ์‚ญ์ œ โœ… ์žˆ์Œ โŒ ์—†์Œ
HEAD GET๊ณผ ๋™์ผ, ์‘๋‹ต ๋ณธ๋ฌธ ์—†์Œ โœ… ์žˆ์Œ โœ… ๊ฐ€๋Šฅ
OPTIONS ์ง€์›ํ•˜๋Š” ๋ฉ”์„œ๋“œ ํ™•์ธ (CORS ๋“ฑ) โœ… ์žˆ์Œ โŒ ์—†์Œ

 

๋ฉฑ๋“ฑ์„ฑ: ๊ฐ™์€ ์š”์ฒญ์„ ์—ฌ๋Ÿฌ ๋ฒˆ ๋ณด๋‚ด๋„ ๊ฒฐ๊ณผ๊ฐ€ ๊ฐ™์Œ → ์•ˆ์ •์„ฑ, ์žฌ์‹œ๋„ ์ „๋žต์— ์ค‘์š”
์บ์‹ฑ: ๋ธŒ๋ผ์šฐ์ €/์„œ๋ฒ„/ํ”„๋ก์‹œ ๋“ฑ์—์„œ ๋ฆฌ์†Œ์Šค๋ฅผ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅ

 

 

๐Ÿ“Œ RESTful API

ํ•ญ๋ชฉ ์ข‹์€ ์„ค๊ณ„ ๋‚˜์œ ์„ค๊ณ„ (RESTful ํ•˜์ง€ ์•Š์Œ)
URL ์„ค๊ณ„ ๋ฆฌ์†Œ์Šค ์ค‘์‹ฌ (/users, /posts/1) ๋™์‚ฌ ์ค‘์‹ฌ (/getUser, /doLogin)
๋ฉ”์„œ๋“œ ์‚ฌ์šฉ CRUD์— ๋งž๊ฒŒ ์‚ฌ์šฉ (GET, POST, PUT, DELETE) ๋ชจ๋“  ๊ธฐ๋Šฅ์„ POST ํ•˜๋‚˜๋กœ ์ฒ˜๋ฆฌ
์ƒํƒœ ์ฝ”๋“œ ์ƒํ™ฉ์— ๋งž๋Š” HTTP ์ƒํƒœ ์ฝ”๋“œ ๋ช…ํ™•ํžˆ ์‚ฌ์šฉ ๋ฌด์กฐ๊ฑด 200๋งŒ ๋ฐ˜ํ™˜, ์˜ค๋ฅ˜๋„ OK ์ฒ˜๋ฆฌ
Stateless ์„œ๋ฒ„๊ฐ€ ์ƒํƒœ ์ €์žฅํ•˜์ง€ ์•Š์Œ (ํ† ํฐ ๊ธฐ๋ฐ˜ ๋“ฑ) ์„œ๋ฒ„๊ฐ€ ์„ธ์…˜์— ์ƒํƒœ ์ €์žฅ
๋ฒ„์ „ ๊ด€๋ฆฌ /v1/users, ํ—ค๋” ๊ธฐ๋ฐ˜ ๋“ฑ ๋ช…์‹œ์  ๋ฒ„์ „ ๊ด€๋ฆฌ ๋ฒ„์ „ ๊ตฌ๋ถ„ ์—†์Œ

 

 

๐Ÿ“Œ ์กฐ๊ฑด๋ถ€ ์š”์ฒญ & ์บ์‹ฑ ๊ด€๋ จ ํ—ค๋”

ํ—ค๋” ์„ค๋ช…
ETag ๋ฆฌ์†Œ์Šค์˜ ๊ณ ์œ  ๋ฒ„์ „ ์‹๋ณ„์ž
If-None-Match ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ฐ€์ง„ ETag๊ณผ ๋น„๊ตํ•ด์„œ ๊ฐ™์œผ๋ฉด 304
Last-Modified ๋ฆฌ์†Œ์Šค ๋งˆ์ง€๋ง‰ ์ˆ˜์ • ์‹œ๊ฐ
If-Modified-Since ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ฐ€์ง„ ๋งˆ์ง€๋ง‰ ์ˆ˜์ • ์‹œ๊ฐ๊ณผ ๋น„๊ต
Cache-Control ์บ์‹œ ํ—ˆ์šฉ ์—ฌ๋ถ€, ๊ธฐ๊ฐ„ ๋“ฑ ์„ค์ •
Expires ์บ์‹œ ๋งŒ๋ฃŒ ์‹œ๊ฐ ๋ช…์‹œ

 

2. HTTP ๊ด€๋ จ ์งˆ๋ฌธ 

Q1. 401 Unauthorized์™€ 403 Forbidden์˜ ์ฐจ์ด๋Š”?

  • 401: ์ธ์ฆ ์‹คํŒจ → ๋กœ๊ทธ์ธ or ํ† ํฐ ํ•„์š”
    (ex. ํ† ํฐ์ด ์—†๊ฑฐ๋‚˜ ๋งŒ๋ฃŒ๋จ)
  • 403: ์ธ์ฆ์€ ๋˜์—ˆ์ง€๋งŒ ๊ถŒํ•œ ์—†์Œ
    (ex. ์ผ๋ฐ˜ ์œ ์ €๊ฐ€ ๊ด€๋ฆฌ์ž API ์ ‘๊ทผ ์‹œ)

Q2. 200 OK์™€ 204 No Content์˜ ์ฐจ์ด๋Š”?

  • 200 OK: ์š”์ฒญ ์„ฑ๊ณต + ์‘๋‹ต ๋ณธ๋ฌธ ์žˆ์Œ
  • 204 No Content: ์š”์ฒญ ์„ฑ๊ณต + ์‘๋‹ต ๋ณธ๋ฌธ ์—†์Œ
    (ex. DELETE ์„ฑ๊ณต ํ›„ ๋‚ด์šฉ ๋ฐ˜ํ™˜ ํ•„์š” ์—†์„ ๋•Œ)

Q3. RESTfulํ•˜์ง€ ์•Š์€ API ์„ค๊ณ„์˜ ์˜ˆ์‹œ๋Š”?

  • ๋ชจ๋“  ๊ธฐ๋Šฅ์„ POST /doSomething ์‹์œผ๋กœ ์„ค๊ณ„
  • URL์ด ๋™์‚ฌ ์œ„์ฃผ (/createUser, /getData)
  • ์„œ๋ฒ„๊ฐ€ ํด๋ผ์ด์–ธํŠธ์˜ ์ƒํƒœ๋ฅผ ๊ธฐ์–ตํ•˜๋Š” ๊ตฌ์กฐ (REST๋Š” Stateless๊ฐ€ ์›์น™)

Q4. ์บ์‹œ์™€ 304 Not Modified๋Š” ์–ด๋–ค ์ƒํ™ฉ์—์„œ ์“ฐ์ด๋‚˜์š”?

  • ์บ์‹ฑ์€ ์„œ๋ฒ„ ๋ถ€ํ•˜ ๊ฐ์†Œ, ์†๋„ ํ–ฅ์ƒ ๋ชฉ์ 
  • ํด๋ผ์ด์–ธํŠธ๊ฐ€ If-Modified-Since ๋˜๋Š” If-None-Match ํ—ค๋” ํฌํ•จ ์š”์ฒญ ์‹œ,
  • ์„œ๋ฒ„ ๋ฆฌ์†Œ์Šค๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด 304 ์‘๋‹ต → ํด๋ผ์ด์–ธํŠธ๋Š” ๊ธฐ์กด ์บ์‹œ ์‚ฌ์šฉ

Q5. PUT๊ณผ PATCH์˜ ์ฐจ์ด๋Š”?

  • PUT: ๋ฆฌ์†Œ์Šค ์ „์ฒด๋ฅผ ์ˆ˜์ • (๋Œ€์ฒด)
  • PATCH: ๋ฆฌ์†Œ์Šค์˜ ์ผ๋ถ€๋ถ„๋งŒ ์ˆ˜์ •
    → ๋‘˜ ๋‹ค ๋ฉฑ๋“ฑ์„ฑ์„ ๊ฐ€์ง€์ง€๋งŒ ์˜๋ฏธ๋Š” ๋‹ค๋ฆ„

Q6. 405 Method Not Allowed๋Š” ์–ธ์ œ ๋ฐœ์ƒํ•˜๋‚˜์š”?

  • ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์กด์žฌํ•˜๋Š” URL์— ๋Œ€ํ•ด ํ—ˆ์šฉ๋˜์ง€ ์•Š์€ HTTP ๋ฉ”์„œ๋“œ๋กœ ์š”์ฒญํ•  ๋•Œ ๋ฐœ์ƒ
    (ex. GET /users/1๋งŒ ํ—ˆ์šฉ์ธ๋ฐ POST๋กœ ์š”์ฒญํ•จ)

Q7. ๋ฉฑ๋“ฑ์„ฑ(Idempotent)๊ณผ ๊ด€๋ จ๋œ HTTP ๋ฉ”์„œ๋“œ๋Š”?

  • ๋ฉฑ๋“ฑ์„ฑ ์žˆ์Œ: GET, PUT, DELETE, HEAD, OPTIONS
  • ๋ฉฑ๋“ฑ์„ฑ ์—†์Œ: POST
    → ๊ฐ™์€ ์š”์ฒญ์„ ์—ฌ๋Ÿฌ ๋ฒˆ ๋ณด๋‚ด๋„ ๊ฒฐ๊ณผ๊ฐ€ ๊ฐ™์•„์•ผ ๋ฉฑ๋“ฑ

Q8. 429 Too Many Requests๋Š” ์–ธ์ œ ๋ฐœ์ƒํ•˜๋‚˜์š”?

  • ์‚ฌ์šฉ์ž๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์€ ์š”์ฒญ์„ ์งง์€ ์‹œ๊ฐ„์— ๋ณด๋ƒˆ์„ ๋•Œ
  • ์ฃผ๋กœ Rate Limit ์ ์šฉ ์‹œ ๋ฐœ์ƒ
  • Retry-After ํ—ค๋”๋ฅผ ํ†ตํ•ด ์žฌ์‹œ๋„ ์‹œ์  ๋ช…์‹œ ๊ฐ€๋Šฅ

Q9. 502 Bad Gateway vs 504 Gateway Timeout ์ฐจ์ด?

  • 502: ํ”„๋ก์‹œ ์„œ๋ฒ„๊ฐ€ ๋’ค์ชฝ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ์ž˜๋ชป๋œ ์‘๋‹ต์„ ๋ฐ›์Œ
  • 504: ํ”„๋ก์‹œ ์„œ๋ฒ„๊ฐ€ ๋’ค์ชฝ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ์‘๋‹ต์„ ๋ชป ๋ฐ›๊ณ  ํƒ€์ž„์•„์›ƒ

Q10. OPTIONS ๋ฉ”์„œ๋“œ๋Š” ์–ธ์ œ ์‚ฌ์šฉํ•˜๋‚˜์š”?

  • ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„์— ์š”์ฒญ ๊ฐ€๋Šฅ ๋ฉ”์„œ๋“œ์™€ CORS ๊ด€๋ จ ์ •๋ณด๋ฅผ ๋ฏธ๋ฆฌ ์š”์ฒญํ•  ๋•Œ ์‚ฌ์šฉ
  • ์ฃผ๋กœ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ Preflight Request๋กœ ์ž๋™ ๋ณด๋ƒ„
  • ์‘๋‹ต์—” Access-Control-Allow-* ํ—ค๋” ํฌํ•จ