HTTP Content Negotiation ํบ์๋ณด๊ธฐ ๐ฃ๏ธ
์น์์ ๋ฐ์ดํฐ๊ฐ ์ค๊ฐ๋ ๊ณผ์ ์ ๋ง์น “๋ฉ๋ดํ์ ๋ณด๊ณ ์๋ฆฌ๋ฅผ ์ฃผ๋ฌธํ๋ ์๋๊ณผ ์ ฐํ” ๊ฐ์ ๋ํ๋ก ์ด๋ฃจ์ด์ ธ์. ํด๋ผ์ด์ธํธ(์๋)๋ ์์ ์ด ์ด๋ค ํ์์ ๋ฐ์ดํฐ๋ฅผ ์ํ๋์ง “์์ฒญ”ํ๊ณ , ์๋ฒ(์ ฐํ)๋ ๊ทธ์ ๋ง๋ ๋ฐ์ดํฐ๋ฅผ “์๋ต”ํฉ๋๋ค. ์ด ๋ํ ๊ณผ์ ์ HTTP์์๋ Content Negotiation(์ฝํ ์ธ ํ์)์ด๋ผ๊ณ ๋ถ๋ฌ์. ๐ง๐ณ
๐ฝ๏ธ Content Negotiation์ด๋?
Content Negotiation์ ํด๋ผ์ด์ธํธ์ ์๋ฒ ๊ฐ์ ๋ฐ์ดํฐ ํ์๊ณผ ํํ ๋ฐฉ์์ ์กฐ์จํ๋ HTTP ๋ฉ์ปค๋์ฆ์ด์์.
์ฆ, ํด๋ผ์ด์ธํธ๊ฐ “JSON์ผ๋ก ์ฃผ์ธ์!“๋ผ๊ณ ์์ฒญํ๋ฉด, ์๋ฒ๊ฐ ๊ทธ์ ๋ง๋ ํ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๊ณตํ๋ ๊ฒ์ด์ฃ .
์ ํ์ํ ๊น?
- ๋ค์ํ ํด๋ผ์ด์ธํธ ์ง์: ๋ธ๋ผ์ฐ์ , ๋ชจ๋ฐ์ผ ์ฑ, IoT ๊ธฐ๊ธฐ ๋ฑ ์์ฒญํ๋ ํ๊ฒฝ์ด ๋ค ๋ค๋ฅด๊ธฐ ๋๋ฌธ
- ํจ์จ์ ์ธ ๋ฐ์ดํฐ ์ ์ก: ํด๋ผ์ด์ธํธ๊ฐ ํ์๋ก ํ๋ ์ต์ํ์ ๋ฐ์ดํฐ๋ง ์ ์กํด ์ฑ๋ฅ์ ์ต์ ํ
- ๋ค๊ตญ์ด ์ง์: ์ฌ์ฉ์์ ์ธ์ด ์ค์ ์ ๋ฐ๋ผ ์ฝํ ์ธ ๋ฅผ ๋ค๋ฅด๊ฒ ์ ๊ณต.
๐ ๏ธ Content Negotiation์ ์๋ ๋ฐฉ์
ํด๋ผ์ด์ธํธ๋ HTTP ์์ฒญ ํค๋๋ฅผ ํตํด ์์ ์ด ์ ํธํ๋ ๋ฐ์ดํฐ๋ฅผ ์๋ฒ์ ์๋ ค์ค๋๋ค.
์๋ฒ๋ ์ด๋ฅผ ํด์ํด ๊ฐ์ฅ ์ ํฉํ ํ์์ผ๋ก ์๋ตํฉ๋๋ค.
๐งพ ์ฃผ์ HTTP ํค๋๋ค
1๏ธโฃ Accept
ํด๋ผ์ด์ธํธ๊ฐ ๋ฐ๊ณ ์ถ์ ๋ฏธ๋์ด ํ์ (ex: text/html, application/json)์ ์ง์ .
Accept: application/json, text/html
2๏ธโฃ Accept-Language
ํด๋ผ์ด์ธํธ๊ฐ ์ ํธํ๋ ์ธ์ด๋ฅผ ์ง์
Accept-Language: en-US, fr;q=0.8, ko;q=0.6
์ฌ๊ธฐ์ q๋ ํ์ง ์ง์๋ก, ์ ํธ๋๋ฅผ ๋ํ๋ ๋๋ค. (1.0์ด ๊ฐ์ฅ ๋๊ณ , 0.0์ ์์ ์ง์ํ์ง ์์์ ์๋ฏธ)
3๏ธโฃ Accept-Encoding
๋ฐ์ดํฐ๋ฅผ ์ ์กํ ๋ ์ฌ์ฉํ ์์ถ ๋ฐฉ์์ ์ง์ .
Accept-Encoding: gzip, deflate, br
4๏ธโฃ User-Agent
ํด๋ผ์ด์ธํธ์ ๋๋ฐ์ด์ค ์ ๋ณด(๋ธ๋ผ์ฐ์ , OS ๋ฑ)๋ฅผ ํฌํจ.
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Content Negotiation์ ์ข ๋ฅ ๐
1. ์๋ฒ ์ฃผ๋ ํ์(Server-Driven Negotiation)
์๋ฒ๊ฐ ํด๋ผ์ด์ธํธ์ ์์ฒญ ํค๋๋ฅผ ๋ณด๊ณ ์๋์ผ๋ก ์ต์ ์ ๋ฐ์ดํฐ๋ฅผ ์ ํํ๋ ๋ฐฉ์
- ์ฅ์ : ํด๋ผ์ด์ธํธ๊ฐ ๊ฐ๋จํ ์์ฒญํ ์ ์์
- ๋จ์ : ์๋ฒ๊ฐ ํด๋ผ์ด์ธํธ์ ์ ํธ๋๋ฅผ 100% ์๊ธฐ ์ด๋ ต๊ณ , ์๋ต ์๋๊ฐ ๋๋ ค์ง ์ ์์
GET /resource HTTP/1.1
Host: example.com
Accept: application/json, text/html
์๋ฒ ์๋ต ์์:
HTTP/1.1 200 OK
Content-Type: application/json
2. ํด๋ผ์ด์ธํธ ์ฃผ๋ ํ์(Client-Driven Negotiation)
ํด๋ผ์ด์ธํธ๊ฐ ์์ฒญ ์ ์ํ๋ ๋ฐ์ดํฐ๋ฅผ ๋ช ์์ ์ผ๋ก ์ง์ ํ๋ ๋ฐฉ์
- ์ฅ์ : ํด๋ผ์ด์ธํธ๊ฐ ์ ํํ ์ํ๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ ์ ์์
- ๋จ์ : ํด๋ผ์ด์ธํธ๊ฐ ๋ชจ๋ ์ต์ ์ ์์์ผ ํจ
GET /resource.json HTTP/1.1
Host: example.com
์๋ฒ ์๋ต ์์:
HTTP/1.1 200 OK
Content-Type: application/json
3. ํฌ๋ช ํ์(Transparent Negotiation)
์๋ฒ์ ํด๋ผ์ด์ธํธ๊ฐ ํ๋ก์ ์๋ฒ๋ฅผ ํตํด ํ๋ ฅํ์ฌ ์ต์ ์ ๋ฐ์ดํฐ๋ฅผ ๊ฒฐ์ ํ๋ ๋ฐฉ์
ํด๋ผ์ด์ธํธ์ ์๋ฒ ๊ฐ์ ํ์์ด ํผํฉ๋ ํํ๋ก, ์ค์ ๋ก๋ ์ ์ฌ์ฉ๋์ง ์์์.
๐ป ์ค๋ฌด์์์ Content Negotiation ์์
1๏ธโฃ JSON vs HTML
REST API ์๋ฒ์์ ํด๋ผ์ด์ธํธ๊ฐ JSON ๋ฐ์ดํฐ ๋๋ HTML์ ์์ฒญํ ์ ์๋ ๊ฒฝ์ฐ
ํด๋ผ์ด์ธํธ ์์ฒญ:
GET /users HTTP/1.1
Accept: application/json, text/html
์๋ฒ ์๋ต (JSON):
HTTP/1.1 200 OK
Content-Type: application/json
{
"users": [
{ "id": 1, "name": "Alice" },
{ "id": 2, "name": "Bob" }
]
}
2๏ธโฃ ์ธ์ด์ ๋ฐ๋ฅธ ์ฝํ ์ธ ์ ๊ณต
๋ค๊ตญ์ด ์ง์ ์น์ฌ์ดํธ์์ ์ฌ์ฉ์์ ์ธ์ด์ ๋ง๋ ์ฝํ ์ธ ๋ฅผ ์ ๊ณต.
ํด๋ผ์ด์ธํธ ์์ฒญ:
GET /home HTTP/1.1
Accept-Language: fr, en;q=0.8, es;q=0.6
์๋ฒ ์๋ต (ํ๋์ค์ด ์ฝํ ์ธ ):
HTTP/1.1 200 OK
Content-Language: fr
<!DOCTYPE html>
<html lang="fr">
<head><title>Bienvenue</title></head>
<body><h1>Bienvenue sur notre site!</h1></body>
</html>
โ ๏ธ Content Negotiation์ ํ๊ณ์ ์ฃผ์์ฌํญ
1๏ธโฃ ์๋ฒ ์ฃผ๋ ํ์์ ๋ถํ์ค์ฑ
ํด๋ผ์ด์ธํธ์ ์ ํธ๋๋ฅผ 100% ๋ง์กฑ์ํค์ง ๋ชปํ ์ ์์.
2๏ธโฃ ํด๋ผ์ด์ธํธ ์ฃผ๋ ํ์์ ๋ณต์ก์ฑ
ํด๋ผ์ด์ธํธ๊ฐ ๋ช ํํ ์์ฒญํด์ผ ํ๋ฏ๋ก, ๋ชจ๋ ์ต์ ์ ์๊ณ ์์ด์ผ ํจ.
3๏ธโฃ ์บ์ฑ ๋ฌธ์
์๋ก ๋ค๋ฅธ ํค๋๋ก ์์ฒญํ ๊ฒฐ๊ณผ๋ฅผ ์บ์ฑํ ๋ ์ถฉ๋ ๊ฐ๋ฅ์ฑ์ด ์์.
์ด๋ฅผ ํด๊ฒฐํ๋ ค๋ฉด Vary ํค๋๋ฅผ ์ฌ์ฉ.
Vary: Accept, Accept-Language
๐ค Content Negotiation์ ์ ์ค์ํ ๊น?
- ์ฌ์ฉ์ ๊ฒฝํ ๊ฐ์ : ๊ฐ ์ฌ์ฉ์์ ํ๊ฒฝ๊ณผ ์ ํธ๋์ ๋ง๋ ์ฝํ ์ธ ์ ๊ณต
- ์ฑ๋ฅ ์ต์ ํ: ํ์ํ ๋ฐ์ดํฐ๋ง ํจ์จ์ ์ผ๋ก ์ ์ก
- SEO์ ์ ๊ทผ์ฑ ๊ฐํ: ๊ฒ์ ์์ง๊ณผ ๋ค์ํ ๋๋ฐ์ด์ค์ ๋์.
Content Negotiation์ ์ ๋๋ก ์ดํดํ๊ณ ํ์ฉํ๋ฉด, ํด๋ผ์ด์ธํธ์ ์๋ฒ ๊ฐ์ ๋ํ๋ฅผ ํจ์ฌ ์ค๋งํธํ๊ฒ ๋ง๋ค ์ ์์ด์. ์ฌ์ฉ์์๊ฒ ๊ผญ ๋ง๋ ์ฝํ ์ธ ๋ฅผ ์ ๊ณตํ๋ ๊ฑด ๊ธฐ๋ณธ, ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ํ์ง์ ํ ๋จ๊ณ ๋์ด์ฌ๋ฆด ์ ์๋ต๋๋ค! ๐
๐ท์ ์ค์ ๊ฐ๋ฐ์๊ฐ ๋์ด๋ด ์๋น!๐ท