HTTP ์ํ ์ฝ๋ ์์ ์ ๋ฆฌ. 200, 404, 500์ ์๊ฒ ๋๋ฐ 401๊ณผ 403์ ์ฐจ์ด๋? 204๋ ์ธ์ ์ฐ์ง? ๋ฐฑ์๋ ๊ฐ๋ฐ์๊ฐ API๋ฅผ ์ค๊ณํ ๋ ๊ผญ ์์์ผ ํ HTTP ์ํ ์ฝ๋๋ฅผ, ์์ฃผ ์ฐ๋ ๊ฒ ์์ฃผ๋ก ์ค๋ฌด ๊ธฐ์ค๊ณผ ํจ๊ป ์ ๋ฆฌํ๋ค.
๋ค์ด๊ฐ๋ฉฐ
API๋ฅผ ๋ง๋ค๋ค ๋ณด๋ฉด "์ด ์ํฉ์ ๋ฌด์จ ์ํ ์ฝ๋๋ฅผ ์ค์ผ ํ์ง?" ํ๊ณ ๋ฉ์นซํ๋ ์๊ฐ์ด ์จ๋ค. ์ฑ๊ณต์ด๋ฉด 200, ๋ชป ์ฐพ์ผ๋ฉด 404 ์ ๋๋ ์ธ์ฐ์ง๋ง, ๋ง์ "์๋ชป๋ ์์ฒญ์ธ๋ฐ 401์ด์ผ 400์ด์ผ?", "์ญ์ ์ฑ๊ณต์ 200์ด์ผ 204์ผ?" ๊ฐ์ ๋ฐ์ ํท๊ฐ๋ฆฐ๋ค.
HTTP ์ํ ์ฝ๋๋ ๋จ์ํ ์ซ์๊ฐ ์๋๋ผ, ์๋ฒ๊ฐ ํด๋ผ์ด์ธํธ์๊ฒ ๊ฒฐ๊ณผ๋ฅผ ์๋ ค์ฃผ๋ ์ฝ์๋ ์ธ์ด๋ค. ์ ๋๋ก ์ฐ๋ฉด API๋ฅผ ์ฐ๋ ์ฌ๋์ด ์๋ต๋ง ๋ณด๊ณ ๋ ๋ฌด์จ ์ผ์ด ์ผ์ด๋ฌ๋์ง ์๋ค. ๋ฐ๋๋ก ์๋ฌด ์ฝ๋๋ ๋์ง๋ฉด(๋ค 200์ผ๋ก ์ฃผ๊ฑฐ๋) API์ ์ ๋ขฐ๋๊ฐ ๋จ์ด์ง๋ค.
์ข์ API๋ ์ํ ์ฝ๋๋ง ๋ด๋ ๋ฌด์จ ์ผ์ด ์ผ์ด๋ฌ๋์ง ์ ์ ์๋ค. ์ํ ์ฝ๋๋ ์๋ต์ ์์ฝ์ด๋ค.
์ด ๊ธ์์๋ HTTP ์ํ ์ฝ๋๋ฅผ ๋ถ๋ฅ๋ณ๋ก, ๊ทธ๋ฆฌ๊ณ ์ค๋ฌด์์ ์์ฃผ ์ฐ๋ ๊ฒ ์์ฃผ๋ก ์ ๋ฆฌํ๋ค.
5๊ฐ์ ํฐ ๋ถ๋ฅ
์ํ ์ฝ๋๋ ์ธ ์๋ฆฌ ์ซ์์ด๊ณ , ๋งจ ์์๋ฆฌ๊ฐ ๊ทธ ์ฑ๊ฒฉ์ ๋ํ๋ธ๋ค. ์ด๊ฒ๋ง ์์๋ ์ ๋ฐ์ ์๋ค.
| ๋ถ๋ฅ | ์๋ฏธ | ํ ์ค ์์ฝ |
| 1xx | ์ ๋ณด | ์์ฒญ์ ๋ฐ์๊ณ ์ฒ๋ฆฌ ์ค (๊ฑฐ์ ์ง์ ์ ์) |
| 2xx | ์ฑ๊ณต | ์์ฒญ์ด ์ ์ ์ฒ๋ฆฌ๋จ |
| 3xx | ๋ฆฌ๋ค์ด๋ ์ | ๋ค๋ฅธ ๊ณณ์ผ๋ก ์ด๋ํด์ผ ํจ |
| 4xx | ํด๋ผ์ด์ธํธ ์ค๋ฅ | ์์ฒญํ ์ชฝ์ ์๋ชป |
| 5xx | ์๋ฒ ์ค๋ฅ | ์๋ฒ ์ชฝ์ ์๋ชป |
ํต์ฌ์ 4xx์ 5xx์ ๊ตฌ๋ถ์ด๋ค. 4xx๋ "๋ค๊ฐ ์๋ชป ๋ณด๋์ด"(ํด๋ผ์ด์ธํธ ์ฑ ์), 5xx๋ "๋ด๊ฐ ์ฒ๋ฆฌํ๋ค ํฐ์ก์ด"(์๋ฒ ์ฑ ์)๋ค. ์ด ๊ตฌ๋ถ๋ง ๋ช ํํด๋ API๊ฐ ํจ์ฌ ์ฝ๊ธฐ ์ฌ์์ง๋ค.
2xx — ์ฑ๊ณต
์์ฒญ์ด ์ฑ๊ณตํ์ ๋๋ค. ๊ทธ๋ฅ ๋ค 200์ผ๋ก ์ฃผ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์๋ฐ, ์ํฉ์ ๋ง๊ฒ ๋๋ ์ฐ๋ฉด ๋ ๋ช ํํ๋ค.
| ์ฝ๋ | ์ด๋ฆ | ์ธ์ ์ฐ๋ |
| 200 | OK | ์ผ๋ฐ์ ์ธ ์ฑ๊ณต (์กฐํ, ์์ ๋ฑ) |
| 201 | Created | ๋ฆฌ์์ค ์์ฑ ์ฑ๊ณต (POST๋ก ์ ๋ฐ์ดํฐ ์์ฑ) |
| 202 | Accepted | ์์ฒญ์ ๋ฐ์์ผ๋ ์ฒ๋ฆฌ๋ ์์ง (๋น๋๊ธฐ ์์ ) |
| 204 | No Content | ์ฑ๊ณตํ์ง๋ง ์๋ต ๋ณธ๋ฌธ์ด ์์ (์ญ์ ๋ฑ) |
์ค๋ฌด ํฌ์ธํธ๋ฅผ ์ง์ผ๋ฉด:
- POST๋ก ์์ฑํ๋ฉด 201์ด ์ ์์ด๋ค. ์ ์ฌ์ฉ์๋ฅผ ๋ง๋ค์์ผ๋ฉด 200๋ณด๋ค 201์ด ์๋ฏธ๊ฐ ๋ถ๋ช
ํ๋ค. ๋ณดํต
Locationํค๋์ ์์ฑ๋ ๋ฆฌ์์ค์ URL์ ํจ๊ป ์ค๋ค. - DELETE ์ฑ๊ณต์ 204๊ฐ ๊น๋ํ๋ค. ์ง์ ์ผ๋ ๋๋ ค์ค ๋ณธ๋ฌธ์ด ์๋ค. ๋ฌผ๋ก ์ญ์ ๊ฒฐ๊ณผ ๋ฉ์์ง๋ฅผ ์ฃผ๊ณ ์ถ์ผ๋ฉด 200๋ ๊ด์ฐฎ๋ค.
- 202๋ ๋น๋๊ธฐ์ฉ์ด๋ค. "์์ 10๋ง ๊ฑด ์ฒ๋ฆฌํด์ค" ๊ฐ์ ์ค๋ ๊ฑธ๋ฆฌ๋ ์์ ์ ํ์ ๋ฃ๊ณ "์ ์ํ์ด"๋ผ๊ณ ๋ตํ ๋ ์ด๋ค.
# ์ฌ์ฉ์ ์์ฑ ์ฑ๊ณต
POST /users
→ HTTP/1.1 201 Created
Location: /users/42
# ์ฌ์ฉ์ ์ญ์ ์ฑ๊ณต
DELETE /users/42
→ HTTP/1.1 204 No Content
4xx — ํด๋ผ์ด์ธํธ ์ค๋ฅ
๊ฐ์ฅ ์์ฃผ, ๊ทธ๋ฆฌ๊ณ ๊ฐ์ฅ ๋ง์ด ํท๊ฐ๋ฆฌ๋ ์์ญ์ด๋ค. ์์ฒญํ ์ชฝ์ ๋ฌธ์ ๊ฐ ์์ ๋๋ค.
| ์ฝ๋ | ์ด๋ฆ | ์ธ์ ์ฐ๋ |
| 400 | Bad Request | ์์ฒญ ํ์·๊ฐ์ด ์๋ชป๋จ (๊ฒ์ฆ ์คํจ) |
| 401 | Unauthorized | ์ธ์ฆ ์ ๋จ (๋ก๊ทธ์ธ ํ์) |
| 403 | Forbidden | ์ธ์ฆ์ ๋์ผ๋ ๊ถํ ์์ |
| 404 | Not Found | ๋ฆฌ์์ค๊ฐ ์กด์ฌํ์ง ์์ |
| 405 | Method Not Allowed | ํ์ฉ๋์ง ์์ HTTP ๋ฉ์๋ |
| 409 | Conflict | ํ์ฌ ์ํ์ ์ถฉ๋ (์ค๋ณต ๋ฑ) |
| 422 | Unprocessable Entity | ํ์์ ๋ง์ผ๋ ์๋ฏธ์ ์ฒ๋ฆฌ ๋ถ๊ฐ |
| 429 | Too Many Requests | ์์ฒญ ํ์ ์ด๊ณผ (์๋ ์ ํ) |
401 vs 403 — ๊ฐ์ฅ ํท๊ฐ๋ฆฌ๋ ํ ์
์ด ๋์ ์ฐจ์ด๊ฐ ๋ฉด์ ๋จ๊ณจ์ด์ ์ค๋ฌด ํผ๋์ ์ฃผ๋ฒ์ด๋ค.
- 401 Unauthorized: "๋ ๋๊ตฌ์ธ์ง ๋ชจ๋ฅด๊ฒ ์ด." ์ธ์ฆ ์์ฒด๊ฐ ์ ๋๋ค. ๋ก๊ทธ์ธ์ ์ ํ๊ฑฐ๋ ํ ํฐ์ด ์๊ฑฐ๋ ๋ง๋ฃ๋์ ๋. ์ฌ์ค ์ด๋ฆ์ด "Unauthorized(์ธ๊ฐ)"์ธ๋ฐ ์๋ฏธ๋ "Unauthenticated(์ธ์ฆ)"๋ผ์ ๋ ํท๊ฐ๋ฆฐ๋ค.
- 403 Forbidden: "๋๊ฐ ๋๊ตฌ์ธ์ง๋ ์์. ๊ทผ๋ฐ ์ด๊ฑด ๊ถํ์ด ์์ด." ๋ก๊ทธ์ธ์ ํ์ง๋ง ๊ทธ ๋ฆฌ์์ค์ ์ ๊ทผํ ์๊ฒฉ์ด ์์ ๋. ์ผ๋ฐ ์ฌ์ฉ์๊ฐ ๊ด๋ฆฌ์ API๋ฅผ ํธ์ถํ ๊ฒฝ์ฐ.
ํ ํฐ ์์ด ์์ฒญ → 401 (๋๊ตฐ์ง ๋ชจ๋ฆ)
์ผ๋ฐ ์ ์ ๊ฐ /admin → 403 (๋๊ตฐ์ง ์์ง๋ง ๊ถํ ์์)
OWASP ์ ๊ทผ ์ ์ด ๊ด์ ์์๋ ์ด ๊ตฌ๋ถ์ ์ค์ํ๋ค. ๋ค๋ง ๋ณด์์ "๋ฆฌ์์ค ์กด์ฌ ์์ฒด๋ฅผ ์จ๊ธฐ๊ณ ์ถ์ ๋"๋ 403 ๋์ 404๋ฅผ ์ฃผ๊ธฐ๋ ํ๋ค.
400 vs 422 — ํ์์ด๋ ์๋ฏธ๋
- 400: ์์ฒญ ์์ฒด๊ฐ ๋ง๊ฐ์ง. JSON ๋ฌธ๋ฒ ์ค๋ฅ, ํ์ ํ๋ ๋๋ฝ ๋ฑ.
- 422: ํ์์ ๋ง๋๋ฐ ๋น์ฆ๋์ค ๊ท์น ์๋ฐ. ์๋ฅผ ๋ค์ด "๋์ด"์ ์์๋ฅผ ๋ณด๋๊ฑฐ๋, ์ด๋ฏธ ๊ฐ์ ๋ ์ด๋ฉ์ผ๋ก ๊ฐ์ ์๋. (ํ๋ ์์ํฌ์ ๋ฐ๋ผ 400์ผ๋ก ํต์ผํด ์ฐ๊ธฐ๋ ํ๋ค.)
409 Conflict์ 429
- 409: "์ด๋ฏธ ์กด์ฌํ๋ ์ด๋ฉ์ผ์ ๋๋ค" ๊ฐ์ ์ถฉ๋ ์ํฉ. ๋์ ์์ ์ผ๋ก ์ธํ ๋ฒ์ ์ถฉ๋์๋ ์ด๋ค.
- 429: API ํธ์ถ์ด ๋๋ฌด ์ฆ์ ๋. OWASP์ ๋ฌด์ ํ ๋ฆฌ์์ค ์๋น ๋ฐฉ์ด์ ์ง๊ฒฐ๋๋ค. ๋ณดํต
Retry-Afterํค๋๋ก "์ธ์ ๋ค์ ์๋ํ๋ผ"๋ฅผ ์๋ ค์ค๋ค.
5xx — ์๋ฒ ์ค๋ฅ
์๋ฒ๊ฐ ์์ฒญ์ ์ฒ๋ฆฌํ๋ค ์คํจํ์ ๋๋ค. ์ด๊ฑด ํด๋ผ์ด์ธํธ ์๋ชป์ด ์๋๋ค.
| ์ฝ๋ | ์ด๋ฆ | ์ธ์ ์ฐ๋ |
| 500 | Internal Server Error | ์๋ฒ ๋ด๋ถ์์ ์ฒ๋ฆฌ๋์ง ์์ ์์ธ |
| 502 | Bad Gateway | ๊ฒ์ดํธ์จ์ด/ํ๋ก์๊ฐ ์๋ชป๋ ์๋ต ๋ฐ์ |
| 503 | Service Unavailable | ์๋ฒ ๊ณผ๋ถํ·์ ๊ฒ์ผ๋ก ์ผ์ ๋ถ๊ฐ |
| 504 | Gateway Timeout | ๊ฒ์ดํธ์จ์ด๊ฐ ์๋ต์ ๊ธฐ๋ค๋ฆฌ๋ค ํ์์์ |
์ค๋ฌด ํฌ์ธํธ:
- 500์ "์ก์ง ๋ชปํ ์์ธ"์ ์ ํธ๋ค. NullPointerException ๊ฐ์ ๊ฒ ๊ทธ๋๋ก ํฐ์ง๋ฉด 500์ด ๋๊ฐ๋ค. 500์ด ์์ฃผ ๋ณด์ธ๋ค๋ฉด ์ฝ๋์ ๋ฒ๊ทธ๊ฐ ์๋ค๋ ๋ป์ด๋ค.
- 502/504๋ ๋ณดํต ์ธํ๋ผ ๋ฌธ์ ๋ค. ๋ก๋๋ฐธ๋ฐ์ ๋ค์ ์๋ฒ๊ฐ ์ฃฝ์๊ฑฐ๋(502), ์๋ต์ด ๋๋ฌด ๋๋ฆด ๋(504). API ์๋ฒ ์ฝ๋๋ณด๋ค ๊ฒ์ดํธ์จ์ด·๋คํธ์ํฌ๋ฅผ ๋ด์ผ ํ๋ค.
- 503์ ์ ๊ฒ·๊ณผ๋ถํ์ฉ์ด๋ค. ์๋์ ์ผ๋ก "์ง๊ธ์ ์๋น์ค ๋ชป ํด"๋ผ๊ณ ์๋ฆด ๋ ์ด๋ค.
์ค์ํ ๊ฑด, ํด๋ผ์ด์ธํธ ์๋ชป์ 500์ผ๋ก ์ฃผ๋ฉด ์ ๋๋ค๋ ์ ์ด๋ค. ์๋ชป๋ ์ ๋ ฅ์ 400๋ฒ๋๋ก ์ค์ผ ํ๋ค. ๋ค 500์ผ๋ก ์ฃผ๋ฉด, API๋ฅผ ์ฐ๋ ์ชฝ์ด "๋ด ์๋ชป์ธ์ง ์๋ฒ ์๋ชป์ธ์ง" ๊ตฌ๋ถ์ ๋ชป ํ๋ค.
์์ฃผ ํ๋ ์ค์
์ค๋ฌด์์ ํํ ๋ณด๋ ์ํฐํจํด๋ค์ด๋ค.
1. ์ ๋ถ 200์ผ๋ก ์ฃผ๊ธฐ
๊ฐ์ฅ ํํ ์ค์. ์๋ฌ๊ฐ ๋๋ 200์ ์ฃผ๊ณ ๋ณธ๋ฌธ์ {"success": false}๋ฅผ ๋ด๋ ์์ด๋ค. ์ด๋ฌ๋ฉด HTTP ํ์ค์ ์ด์ ์ ํต์งธ๋ก ๋ฒ๋ฆฌ๋ ๊ฒ์ด๋ค. ํด๋ผ์ด์ธํธ๊ฐ ๋งค๋ฒ ๋ณธ๋ฌธ์ ๊น๋ด์ผ ์ฑ๊ณต/์คํจ๋ฅผ ์๋ค.
2. ํด๋ผ์ด์ธํธ ์ค๋ฅ๋ฅผ 500์ผ๋ก ์ฃผ๊ธฐ
๊ฒ์ฆ ์คํจ(400์ด์ด์ผ ํ ๊ฒ)๋ฅผ ์ฒ๋ฆฌ ์ ํด์ ์์ธ๊ฐ ํฐ์ง๊ณ 500์ด ๋๊ฐ๋ ๊ฒฝ์ฐ. ์
๋ ฅ ๊ฒ์ฆ์ ์ ๋๋ก ํ๋ฉด 4xx๋ก ์ ํํ ์๋ตํ ์ ์๋ค.
3. 401๊ณผ 403์ ์์ด ์ฐ๊ธฐ
์ธ์ฆ ์ ๋ ๊ฑธ 403์ผ๋ก, ๊ถํ ์๋ ๊ฑธ 401๋ก ์ฃผ๋ ํผ๋. ์์ ๊ตฌ๋ถ์ ๊ธฐ์ตํ์.
4. ์๋ฌ ์๋ต์ ์ ๋ณด๊ฐ ์์
์ํ ์ฝ๋๋ง ์ฃผ๊ณ ๋๋ด์ง ๋ง๊ณ , ๋ณธ๋ฌธ์ "๋ฌด์์ด ์ ์๋ชป๋๋์ง"๋ฅผ ๋ด์์ฃผ๋ ๊ฒ ์ข๋ค.
// ์ข์ ์๋ฌ ์๋ต ์์
{
"status": 400,
"code": "INVALID_EMAIL",
"message": "์ด๋ฉ์ผ ํ์์ด ์ฌ๋ฐ๋ฅด์ง ์์ต๋๋ค",
"field": "email"
}
๋ง์น๋ฉฐ
HTTP ์ํ ์ฝ๋๋ ์ธ์ฐ๋ ๊ฒ ๋ชฉ์ ์ด ์๋๋ผ, API๋ฅผ ์ฐ๋ ์ฌ๋๊ณผ์ ์ฝ์์ด๋ค. ํต์ฌ๋ง ๋ค์ ์ง์ผ๋ฉด ์ด๋ ๋ค. ์์๋ฆฌ๋ก ์ฑ๊ฒฉ์ ๊ฐ๋ฅด๊ณ (2xx ์ฑ๊ณต, 4xx ํด๋ผ์ด์ธํธ ์๋ชป, 5xx ์๋ฒ ์๋ชป), ์์ฃผ ์ฐ๋ ๊ฒ(200·201·204·400·401·403·404·409·429·500)๋ง ์ ํํ ์ฐ๋ฉด ๋๋ถ๋ถ์ ์ํฉ์ ๊น๋ํ๊ฒ ํํํ ์ ์๋ค.
ํนํ 401๊ณผ 403์ ๊ตฌ๋ถ, ๊ทธ๋ฆฌ๊ณ "ํด๋ผ์ด์ธํธ ์ค๋ฅ๋ 4xx, ์๋ฒ ์ค๋ฅ๋ 5xx"๋ผ๋ ์์น๋ง ์ง์ผ๋ API์ ํ์ง์ด ๋์ ๋๊ฒ ์ฌ๋ผ๊ฐ๋ค. ์ํ ์ฝ๋๋ฅผ ์ ๋๋ก ์ฐ๋ API๋, ๋ฌธ์๋ฅผ ๋ ๋ด๋ ๋์์ ์์ธกํ ์ ์๋ค. ๊ทธ๊ฒ ์ข์ API์ ์กฐ๊ฑด์ด๋ค.
์ฐธ๊ณ ์ถ์ฒ
- MDN: HTTP response status codes — https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
- RFC 9110: HTTP Semantics — https://www.rfc-editor.org/rfc/rfc9110.html
- httpstatuses.com — https://httpstatuses.com/
'๐ Tech Stack > Backend' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| @Transactional ์ ๋ฆฌ (0) | 2026.06.22 |
|---|---|
| ๋ฐฐ์น ์ฒ๋ฆฌ vs ์คํธ๋ฆผ ์ฒ๋ฆฌ (1) | 2026.06.18 |
| ์น ์ธ์ฆ ๋ฐฉ์ ๋น๊ต (์ฟ ํค, ์ธ์ , ํ ํฐ) (1) | 2026.06.09 |
| JPA N+1 ์ฌํ๋ถํฐ Fetch Join, Batch Size๊น์ง (0) | 2026.06.03 |
| RestClient๋ก ์ธ๋ถ API ํธ์ถํ๊ธฐ (0) | 2026.05.27 |