์š”์ฒญ ์ผ๊ด„ ์ฒ˜๋ฆฌ

์ด ๋ฌธ์„œ์—์„œ๋Š” API ํ˜ธ์ถœ์„ ์ผ๊ด„ ์ฒ˜๋ฆฌํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜๋Š” HTTP ์—ฐ๊ฒฐ ์ˆ˜๋ฅผ ์ค„์ด๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

์ด ๋ฌธ์„œ์—์„œ๋Š” ํŠนํžˆ HTTP ์š”์ฒญ์„ ๋ณด๋‚ด ์ผ๊ด„ ์š”์ฒญ์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค. Google ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ผ๊ด„ ์š”์ฒญ์„ ํ•˜๋Š” ๊ฒฝ์šฐ ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

๊ฐœ์š”

ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฐ HTTP ์—ฐ๊ฒฐ์—๋Š” ์–ด๋А ์ •๋„์˜ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์ˆ˜๋ฐ˜๋ฉ๋‹ˆ๋‹ค. Compute Engine API๋Š” ์ผ๊ด„ ์ฒ˜๋ฆฌ๋ฅผ ์ง€์›ํ•˜๋ฏ€๋กœ ํด๋ผ์ด์–ธํŠธ์—์„œ ๋‹จ์ผ HTTP ์š”์ฒญ์— ์—ฌ๋Ÿฌ ๊ฐœ์˜ API ํ˜ธ์ถœ์„ ๋„ฃ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ์— ์ผ๊ด„ ์ฒ˜๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • API๋ฅผ ์ด์ œ ๋ง‰ ์‚ฌ์šฉํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ๊ณ  ์—…๋กœ๋“œํ•  ๋ฐ์ดํ„ฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค.
  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์˜คํ”„๋ผ์ธ์ธ ์ƒํƒœ์—์„œ(์ธํ„ฐ๋„ท ์—ฐ๊ฒฐ์ด ๋Š๊น€) ์‚ฌ์šฉ์ž๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋งŽ์€ ์—…๋ฐ์ดํŠธ์™€ ์‚ญ์ œ๋ฅผ ์ „์†กํ•˜์—ฌ ๋กœ์ปฌ ๋ฐ์ดํ„ฐ์™€ ์„œ๋ฒ„๋ฅผ ๋™๊ธฐํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ฐ๊ฐ์˜ ๊ฒฝ์šฐ ๊ฐ ํ˜ธ์ถœ์„ ๊ฐœ๋ณ„์ ์œผ๋กœ ๋ณด๋‚ด๋Š” ๋Œ€์‹  ๋‹จ์ผ HTTP ์š”์ฒญ์œผ๋กœ ๊ทธ๋ฃนํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด๋ถ€ ์š”์ฒญ์€ ๋ชจ๋‘ ๋™์ผํ•œ Google API๋กœ ์ด๋™ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ผ๊ด„ ์š”์ฒญ 1๊ฐœ์— ํฌํ•จํ•  ์ˆ˜ ์žˆ๋Š” ํ˜ธ์ถœ ์ˆ˜๋Š” 1,000๊ฐœ๋กœ ์ œํ•œ๋ฉ๋‹ˆ๋‹ค. ๋” ๋งŽ์ด ํ˜ธ์ถœํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ์ผ๊ด„ ์š”์ฒญ์„ ์—ฌ๋Ÿฌ ๊ฐœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ : Compute Engine API์šฉ ์ผ๊ด„ ์ฒ˜๋ฆฌ ์‹œ์Šคํ…œ์€ OData ์ผ๊ด„ ์ฒ˜๋ฆฌ ์‹œ์Šคํ…œ๊ณผ ๋™์ผํ•œ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜์ง€๋งŒ ์‹œ๋งจํ‹ฑ์Šค๋Š” ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

์ผ๊ด„ ์ฒ˜๋ฆฌ ์„ธ๋ถ€์ •๋ณด

์ผ๊ด„ ์š”์ฒญ์€ ํ•˜๋‚˜์˜ HTTP ์š”์ฒญ์œผ๋กœ ๊ฒฐํ•ฉ๋œ ์—ฌ๋Ÿฌ API ํ˜ธ์ถœ๋กœ ๊ตฌ์„ฑ๋˜๋ฉฐ, ์ด ์š”์ฒญ์„ API ํƒ์ƒ‰ ๋ฌธ์„œ์— ์ง€์ •๋œ batchPath๋กœ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ๊ฒฝ๋กœ๋Š” /batch/api_name/api_version์ž…๋‹ˆ๋‹ค. ์ด ์„น์…˜์—์„œ๋Š” ์ผ๊ด„ ์ฒ˜๋ฆฌ ๊ตฌ๋ฌธ์„ ์„ธ๋ถ€์ ์œผ๋กœ ์„ค๋ช…ํ•˜๋ฉฐ ๋’ท๋ถ€๋ถ„์—์„œ ์˜ˆ์‹œ๋ฅผ ์ œ์‹œํ•ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ : ์ผ๊ด„ ์ฒ˜๋ฆฌ๋œ n๊ฐœ ์š”์ฒญ์˜ ์‚ฌ์šฉ๋Ÿ‰ ํ•œ๋„๋ฅผ ๊ณ„์‚ฐํ•  ๋•Œ๋Š” ์š”์ฒญ ํ•˜๋‚˜๊ฐ€ ์•„๋‹ˆ๋ผ n๊ฐœ๋กœ ๊ณ„์‚ฐ๋ฉ๋‹ˆ๋‹ค. ์ผ๊ด„ ์š”์ฒญ์€ ์ผ๋ จ์˜ ์š”์ฒญ ์ง‘ํ•ฉ์œผ๋กœ ๋ถ„๋ฆฌ๋œ ํ›„ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

์ผ๊ด„ ์š”์ฒญ์˜ ํ˜•์‹

์ผ๊ด„ ์š”์ฒญ์€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ Compute Engine API ํ˜ธ์ถœ์ด ํฌํ•จ๋œ ๋‹จ์ผ ํ‘œ์ค€ HTTP ์š”์ฒญ์ด๋ฉฐ, multipart/mixed ์ฝ˜ํ…์ธ  ์œ ํ˜•์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ธฐ๋ณธ HTTP ์š”์ฒญ ๋‚ด์˜ ๊ฐ ๋ถ€๋ถ„์—๋Š” ์ค‘์ฒฉ๋œ HTTP ์š”์ฒญ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ ๋ถ€๋ถ„์€ ์ž์ฒด Content-Type: application/http HTTP ํ—ค๋”๋กœ ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค. ์„ ํƒ์‚ฌํ•ญ์ธ Content-ID ํ—ค๋”๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ถ€๋ถ„ ํ—ค๋”๋Š” ๋ถ€๋ถ„์˜ ์‹œ์ž‘์„ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด ์žˆ์„ ๋ฟ์ด๋ฉฐ ์ค‘์ฒฉ๋œ ์š”์ฒญ๊ณผ๋Š” ๋ณ„๊ฐœ์ž…๋‹ˆ๋‹ค. ์„œ๋ฒ„์—์„œ ์ผ๊ด„ ์š”์ฒญ์„ ๊ฐœ๋ณ„ ์š”์ฒญ์œผ๋กœ ํ•ด์ฒดํ•˜๋ฉด ๋ถ€๋ถ„ ํ—ค๋”๋Š” ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค.

๊ฐ ๋ถ€๋ถ„์˜ ๋ณธ๋ฌธ์€ ์ž์ฒด ๋™์‚ฌ์™€ URL, ํ—ค๋”, ๋ณธ๋ฌธ์„ ํฌํ•จํ•˜๋Š” ์™„์ „ํ•œ HTTP ์š”์ฒญ์ž…๋‹ˆ๋‹ค. HTTP ์š”์ฒญ์€ URL์˜ ๊ฒฝ๋กœ ๋ถ€๋ถ„๋งŒ ํฌํ•จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ „์ฒด URL์€ ์ผ๊ด„ ์š”์ฒญ์—์„œ ํ—ˆ์šฉ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์™ธ๋ถ€ ์ผ๊ด„ ์š”์ฒญ์˜ HTTP ํ—ค๋”(Content-Type๊ณผ ๊ฐ™์€ Content- ํ—ค๋” ์ œ์™ธ)๋Š” ์ผ๊ด„ ์ฒ˜๋ฆฌ๋˜๋Š” ๊ฐ ์š”์ฒญ์— ๋ชจ๋‘ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. ํŠน์ • HTTP ํ—ค๋”๋ฅผ ์™ธ๋ถ€ ์š”์ฒญ๊ณผ ๊ฐœ๋ณ„ ํ˜ธ์ถœ์— ๋ชจ๋‘ ์ง€์ •ํ•˜๋Š” ๊ฒฝ์šฐ ๊ฐœ๋ณ„ ํ˜ธ์ถœ ํ—ค๋”์˜ ๊ฐ’์ด ์™ธ๋ถ€ ์ผ๊ด„ ์š”์ฒญ ํ—ค๋”์˜ ๊ฐ’์„ ์žฌ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ๋ณ„ ํ˜ธ์ถœ์˜ ํ—ค๋”๋Š” ํ•ด๋‹น ํ˜ธ์ถœ์—๋งŒ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ํŠน์ • ํ˜ธ์ถœ์— ์Šน์ธ ํ—ค๋”๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒฝ์šฐ ์ด ํ—ค๋”๋Š” ํ•ด๋‹น ํ˜ธ์ถœ์—๋งŒ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. ์™ธ๋ถ€ ์š”์ฒญ์— ์Šน์ธ ํ—ค๋”๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒฝ์šฐ ์ด ํ—ค๋”๋Š” ๊ฐœ๋ณ„ ํ˜ธ์ถœ์—์„œ ์ž์ฒด ์Šน์ธ ํ—ค๋”๋กœ ์žฌ์ •์˜ํ•˜์ง€ ์•Š๋Š” ์ด์ƒ ๋ชจ๋“  ๊ฐœ๋ณ„ ํ˜ธ์ถœ์— ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.

์„œ๋ฒ„๋Š” ์ผ๊ด„ ์š”์ฒญ์„ ์ˆ˜์‹ ํ•˜๋ฉด ์™ธ๋ถ€ ์š”์ฒญ์˜ ์ฟผ๋ฆฌ ๋งค๊ฐœ๋ณ€์ˆ˜์™€ ํ—ค๋”๋ฅผ ๊ฐ ๋ถ€๋ถ„์— ์ ์ ˆํžˆ ์ ์šฉํ•œ ๋‹ค์Œ ๊ฐ ๋ถ€๋ถ„์„ ๊ฐœ๋ณ„ HTTP ์š”์ฒญ์ฒ˜๋Ÿผ ์ทจ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค.

์ผ๊ด„ ์š”์ฒญ ์‘๋‹ต

์„œ๋ฒ„ ์‘๋‹ต์€ multipart/mixed ์ฝ˜ํ…์ธ  ์œ ํ˜•์˜ ๋‹จ์ผ ํ‘œ์ค€ HTTP ์‘๋‹ต์ž…๋‹ˆ๋‹ค. ๊ฐ ๋ถ€๋ถ„์€ ์ผ๊ด„ ์š”์ฒญ์— ํฌํ•จ๋œ ์š”์ฒญ ์ค‘ ํ•˜๋‚˜์— ๋Œ€ํ•œ ์‘๋‹ต์ด๋ฉฐ ์š”์ฒญ ์ˆœ์„œ์™€ ๋™์ผํ•œ ์ˆœ์„œ๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

์š”์ฒญ์˜ ๋ถ€๋ถ„๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๊ฐ ์‘๋‹ต ๋ถ€๋ถ„์—๋Š” ์ƒํƒœ ์ฝ”๋“œ, ํ—ค๋”, ๋ณธ๋ฌธ์„ ํฌํ•จํ•œ ์™„์ „ํ•œ HTTP ์‘๋‹ต์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์š”์ฒญ์˜ ๋ถ€๋ถ„๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๊ฐ ์‘๋‹ต ๋ถ€๋ถ„ ์•ž์—๋Š” Content-Type ํ—ค๋”๊ฐ€ ๋ถ™์–ด ๋ถ€๋ถ„์˜ ์‹œ์ž‘์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

์š”์ฒญ์˜ ํŠน์ • ๋ถ€๋ถ„์— Content-ID ํ—ค๋”๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ํ•ด๋‹นํ•˜๋Š” ์‘๋‹ต ๋ถ€๋ถ„์—๋„ ์ผ์น˜ํ•˜๋Š” Content-ID ํ—ค๋”๊ฐ€ ํ‘œ์‹œ๋˜๋ฉฐ ์›๋ž˜ ๊ฐ’ ์•ž์—๋Š” ๋ฌธ์ž์—ด response-๊ฐ€ ๋ถ™์Šต๋‹ˆ๋‹ค(๋‹ค์Œ ์˜ˆ์‹œ ์ฐธ์กฐ).

์ฐธ๊ณ : ์„œ๋ฒ„๋Š” ํ˜ธ์ถœ์„ ์ž„์˜์˜ ์ˆœ์„œ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ง€์ •ํ•œ ์ˆœ์„œ์— ๋”ฐ๋ผ ์‹คํ–‰๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค. 2๊ฐœ์˜ ํ˜ธ์ถœ์ด ์ง€์ •๋œ ์ˆœ์„œ์— ๋”ฐ๋ผ ์‹คํ–‰๋˜๋„๋ก ํ•˜๋ ค๋ฉด 1๊ฐœ์˜ ์š”์ฒญ์œผ๋กœ ๋‘ ํ˜ธ์ถœ์„ ๋ณด๋‚ด๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ํ˜ธ์ถœ์„ ๋‹จ๋…์œผ๋กœ ๋ณด๋‚ธ ๋‹ค์Œ ์ฒซ ๋ฒˆ์งธ ํ˜ธ์ถœ์˜ ์‘๋‹ต์„ ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€ ๋‘ ๋ฒˆ์งธ ํ˜ธ์ถœ์„ ๋ณด๋‚ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ

๋‹ค์Œ์€ Farm API๋ผ๋Š” ์ผ๋ฐ˜(๊ฐ€์ƒ) ๋ฐ๋ชจ API์—์„œ ์ผ๊ด„ ์š”์ฒญ์„ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ์ž…๋‹ˆ๋‹ค. ๊ฐ™์€ ๊ฐœ๋…์ด Compute Engine API์—๋„ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.

์ผ๊ด„ ์š”์ฒญ ์˜ˆ

POST /batch/farm/v1 HTTP/1.1
Authorization: Bearer your_auth_token
Host: www.googleapis.com
Content-Type: multipart/mixed; boundary=batch_foobarbaz
Content-Length: total_content_length

--batch_foobarbaz
Content-Type: application/http
Content-ID: <item1:12930812@barnyard.example.com>

GET /farm/v1/animals/pony

--batch_foobarbaz
Content-Type: application/http
Content-ID: <item2:12930812@barnyard.example.com>

PUT /farm/v1/animals/sheep
Content-Type: application/json
Content-Length: part_content_length
If-Match: "etag/sheep"

{
  "animalName": "sheep",
  "animalAge": "5"
  "peltColor": "green",
}

--batch_foobarbaz
Content-Type: application/http
Content-ID: <item3:12930812@barnyard.example.com>

GET /farm/v1/animals
If-None-Match: "etag/animals"

--batch_foobarbaz--

์ผ๊ด„ ์‘๋‹ต ์˜ˆ์‹œ

์ด์ „ ์„น์…˜์˜ ์š”์ฒญ ์˜ˆ์‹œ์— ๋Œ€ํ•œ ์‘๋‹ต์ž…๋‹ˆ๋‹ค.

HTTP/1.1 200
Content-Length: response_total_content_length
Content-Type: multipart/mixed; boundary=batch_foobarbaz

--batch_foobarbaz
Content-Type: application/http
Content-ID: <response-item1:12930812@barnyard.example.com>

HTTP/1.1 200 OK
Content-Type application/json
Content-Length: response_part_1_content_length
ETag: "etag/pony"

{
  "kind": "farm#animal",
  "etag": "etag/pony",
  "selfLink": "/farm/v1/animals/pony",
  "animalName": "pony",
  "animalAge": 34,
  "peltColor": "white"
}

--batch_foobarbaz
Content-Type: application/http
Content-ID: <response-item2:12930812@barnyard.example.com>

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: response_part_2_content_length
ETag: "etag/sheep"

{
  "kind": "farm#animal",
  "etag": "etag/sheep",
  "selfLink": "/farm/v1/animals/sheep",
  "animalName": "sheep",
  "animalAge": 5,
  "peltColor": "green"
}

--batch_foobarbaz
Content-Type: application/http
Content-ID: <response-item3:12930812@barnyard.example.com>

HTTP/1.1 304 Not Modified
ETag: "etag/animals"

--batch_foobarbaz--