HTTP QUERY method เป็น request method ใหม่ที่นิยามไว้ใน RFC 10008 (มิถุนายน 2026) ซึ่งส่ง query ไปใน request body และทั้งปลอดภัย (safe) และ idempotent คิดซะว่ามันคือ GET ที่มี body: คุณได้พื้นที่ของ POST สำหรับ filter ที่ซับซ้อน และได้การรับประกันของ GET สำหรับ caching และการ retry อัตโนมัติ
ถ้าคุณเคยยัด filter ขนาด 3 KB ลงใน URL หรือส่งการค้นหาแบบอ่านอย่างเดียวเป็น POST แล้วเห็นว่า cache และตรรกะการ retry ของคุณไม่สนใจมัน QUERY คือทางแก้ คู่มือนี้ครอบคลุมว่า spec ระบุอะไรบ้าง QUERY เปรียบเทียบกับ GET และ POST อย่างไร อะไรที่รองรับมันในตอนนี้ และวิธีทดสอบ QUERY endpoint ด้วย coding agent ของคุณ
HTTP QUERY method คืออะไร?
QUERY เป็น HTTP method ที่ขอให้ target resource รัน query ที่อธิบายไว้ใน request content แล้วส่งผลลัพธ์กลับมา request body และ Content-Type ของมันเป็นตัวกำหนด query method นี้เป็น safe (client คาดว่าจะไม่มีการเปลี่ยนแปลง state) และ idempotent (ทำซ้ำแล้วได้ผลเหมือนเดิม) ดังนั้น client, proxy และ cache จึงสามารถ retry และ cache มันได้เหมือน GET
spec ฉบับนี้คือ RFC 10008, “The HTTP QUERY Method” ซึ่งเป็น Proposed Standard ที่เผยแพร่เมื่อมิถุนายน 2026 โดย Julian Reschke (greenbytes), James M. Snell (Cloudflare) และ Mike Bishop (Akamai) IANA ได้เพิ่มมันเข้าใน HTTP Method Registry ด้วยสถานะ “safe: yes, idempotent: yes” อยู่ข้าง ๆ method SEARCH ยุค WebDAV ที่มันเกือบกลายเป็น
request แบบ QUERY มีหน้าตาแบบนี้:
QUERY /contacts HTTP/1.1
Host: example.org
Content-Type: application/x-www-form-urlencoded
Accept: application/json
select=surname,givenname,email&limit=10&match=%22email=*@example.*%22
เซิร์ฟเวอร์ตอบกลับด้วย 200 OK พร้อมผลลัพธ์ใน body
ทำไม GET และ POST ถึงไม่พอ
ก่อนจะมี QUERY คุณมีสองทางเลือกสำหรับการอ่านที่ซับซ้อน และทั้งคู่ก็มีจุดรั่ว
GET ยัดทุกอย่างลงใน URL RFC 10008 ระบุปัญหาสี่ข้อของแนวทางนี้:
- ขีดจำกัดขนาดไม่อาจรู้ล่วงหน้าได้ เพราะ request ต้องผ่านหลายระบบ RFC 9110 เพียงแนะนำว่าผู้ส่งและผู้รับควรรองรับอย่างน้อย 8,000 octets
- การ encode ข้อมูลที่มีโครงสร้างให้เป็น URI ที่ถูกต้องนั้นสิ้นเปลือง
- URI ถูกบันทึกใน log และถูก bookmark บ่อยกว่า request body มาก ซึ่งเป็นปัญหาด้านความเป็นส่วนตัวสำหรับ filter ที่อ่อนไหว
- ทุก combination ของ input ของ query กลายเป็น resource ของตัวเอง
GET ที่มี body ก็ไม่ใช่คำตอบเช่นกัน RFC 9110 กล่าวว่า content ใน GET request ไม่มีความหมายที่นิยามไว้ บางเซิร์ฟเวอร์อ่านมัน บางตัวทิ้งมัน และบาง proxy ก็ปฏิเสธ request นั้น คุณพึ่งพามันตลอดเส้นทางไม่ได้
POST ใช้ได้ แต่ให้ข้อมูลผิดเกี่ยวกับเจตนา การค้นหาด้วย POST ทำงานได้ไม่มีปัญหา แต่ไม่มีอะไรบอก client, cache, proxy หรือ retry library ว่าการดำเนินการนี้เป็นแบบอ่านอย่างเดียว ดังนั้น cache จึงข้ามมันไป และ client จะไม่ retry มันหลังการเชื่อมต่อหลุด ถ้าคุณเคยต้องพ่วง idempotency key เข้ากับการอ่านล้วน ๆ เพียงเพื่อให้การ retry ปลอดภัย คุณก็คงรู้สึกแบบนี้มาแล้ว
QUERY เก็บ body ของ POST ไว้ และเพิ่มการรับประกันของ GET เข้าไป
QUERY vs GET vs POST
นี่คือการเปรียบเทียบ โดยอ้างอิงจาก Table 1 ของ RFC 10008:
| คุณสมบัติ | GET | QUERY | POST |
|---|---|---|---|
| Safe | ใช่ | ใช่ | อาจไม่ใช่ |
| Idempotent | ใช่ | ใช่ | อาจไม่ใช่ |
| Request body | ไม่มีความหมายที่นิยามไว้ | คาดว่ามี และเป็นตัวกำหนด query | คาดว่ามี |
| URI สำหรับตัว query เอง | มี ตามนิยาม | ไม่บังคับ ผ่าน Location |
ไม่มี |
| URI สำหรับผลลัพธ์ | ไม่บังคับ ผ่าน Content-Location |
ไม่บังคับ ผ่าน Content-Location |
ไม่บังคับ ผ่าน Content-Location |
| Cacheable | ได้ | ได้ โดย body เป็นส่วนหนึ่งของ cache key | เฉพาะเมื่อตามด้วย GET หรือ HEAD |
| CORS preflight จากเบราว์เซอร์ | ไม่ต้อง สำหรับ simple request | ทุกครั้ง | ไม่ต้อง สำหรับ simple request |
สรุปสั้น ๆ: ใช้ GET เมื่อ query พอดีกับ URL อย่างสบาย ๆ ใช้ QUERY เมื่อมันไม่พอ และใช้ POST เฉพาะเมื่อ request เปลี่ยน state หากอยากทบทวน method ดั้งเดิม ดูคู่มือของเราเกี่ยวกับ HTTP methods และ GET vs POST
RFC 10008 นิยามอะไรบ้าง
Content-Type เป็นสิ่งที่บังคับ
เซิร์ฟเวอร์ MUST ปฏิเสธ QUERY ที่ไม่มี Content-Type หรือมีไม่สอดคล้องกับ body RFC แนะนำ status code เหล่านี้:
- 400 Bad Request: ไม่มี media type หรือเป็น type ที่ไม่ตรงกับ content เซิร์ฟเวอร์ไม่สามารถ sniff body แล้ว override ได้
- 415 Unsupported Media Type: resource ไม่รองรับรูปแบบ query นั้น
- 422 Unprocessable Content: รูปแบบใช้ได้ แต่ query รันไม่ได้ เช่น SQL ที่อ้างถึงตารางที่ไม่มีอยู่
- 406 Not Acceptable: client ขอ response type ที่ resource ผลิตให้ไม่ได้
Location และ Content-Location
เซิร์ฟเวอร์สามารถส่ง header แบบไม่บังคับสองตัวที่ทำให้ QUERY กลายเป็นสิ่งที่คุณ GET ทีหลังได้:
Content-Locationชี้ไปยังผลลัพธ์ที่จัดเก็บไว้ของรันนี้โดยเฉพาะ ซึ่งอาจเป็นชั่วคราวLocationชี้ไปยังตัว query ที่จัดเก็บไว้ การ GET ที่ URI นั้นจะรัน query ซ้ำด้วยข้อมูลใหม่ โดยไม่ต้องส่ง body ไปอีก
RFC แนะนำให้ client เปลี่ยนไปใช้ GET ที่ URI ใน Location สำหรับ request ที่ทำซ้ำ เพราะ caching ของ GET นั้นเรียบง่ายกว่า หากคุณส่ง header ใดก็ตามเหล่านี้สำหรับ query ที่มีข้อมูลอ่อนไหว URI SHOULD NOT มีส่วนที่เป็นข้อมูลอ่อนไหวของ body ต้นฉบับ
Caching
response ของ QUERY สามารถ cache ได้ cache key MUST ประกอบด้วย request content และ metadata ที่เกี่ยวข้อง เช่น media type cache MAY normalize body ก่อน เช่น โดยการลบ content encoding หรือ normalize JSON สำหรับ type +json เพื่อให้ได้ hit มากขึ้น spec เตือนว่า normalization ที่ผิดพลาดอาจคืน response ที่ผิดได้ ดังนั้นคาดว่า CDN จะระมัดระวังตรงจุดนี้
Redirects
301, 302, 307 หรือ 308 หมายความว่า “ส่ง QUERY เดิมไปยัง URI ใหม่” ต่างจาก POST ตรงที่ QUERY ต้องไม่ถูกเขียนใหม่เป็น GET เมื่อเจอ 301 หรือ 302 ส่วน 303 See Other หมายความว่า “ดึงผลลัพธ์ด้วย GET ที่ URI นี้”
header Accept-Query
Accept-Query เป็น response header ใหม่ที่ประกาศว่ารองรับ QUERY และระบุรูปแบบ query ที่ resource ยอมรับ มันเป็นรายการแบบ Structured Field ดังนั้นให้ parse เป็นรายการ:
Accept-Query: "application/jsonpath", application/sql;charset="UTF-8"
client ยังค้นหาการรองรับได้ด้วย OPTIONS แล้วอ่าน header Allow หรือจะส่ง QUERY ไปเลยแล้วจัดการกับ 405 Method Not Allowed ก็ได้
เครื่องมือไหนรองรับ QUERY ในตอนนี้?
การรองรับยังไม่สม่ำเสมอ ดังนั้นควรทดสอบ stack ของคุณเอง นี่คือสิ่งที่เรายืนยันเมื่อวันที่ 28 ตุลาคม 2026:
| เครื่องมือ | ผลลัพธ์ |
|---|---|
เซิร์ฟเวอร์ http ของ Node.js 24 |
http.METHODS มี QUERY; เซิร์ฟเวอร์ธรรมดาได้รับ method และ body |
fetch ของ Node.js 24 |
ส่ง QUERY พร้อม JSON body ได้ |
| curl 8.7 | curl -X QUERY พร้อม -d ส่ง method และ body ได้ |
http.client ของ Python 3.14 |
ส่ง QUERY พร้อม body ได้ |
| OpenAPI 3.2 | Path Item Object มี field query สำหรับ operation แบบ QUERY |
| Apidog CLI 2.2.12 | schema endpoint-create ยอมรับ "method": "query" |
นี่คือคำสั่ง curl ที่เราใช้ยิงไปยัง Node server ในเครื่อง:
curl -i -X QUERY http://localhost:3000/products \
-H "Content-Type: application/json" \
-d '{"q":"running shoe","limit":2}'
Fetch Standard ห้าม body เฉพาะกับ GET และ HEAD เท่านั้น เบราว์เซอร์จึงส่ง QUERY พร้อม body ได้ อย่างไรก็ตาม QUERY ไม่ใช่ method ที่อยู่ใน CORS safelist ดังนั้นทุก cross-origin QUERY จะ trigger preflight เซิร์ฟเวอร์ของคุณต้องระบุ QUERY ใน Access-Control-Allow-Methods
ช่องว่างอยู่ตรงกลางเครือข่าย: reverse proxy, API gateway, WAF และ CDN ที่ทำ allowlist method หรือไม่ key cache ด้วย body ตรวจสอบทุกจุดที่ request ผ่านก่อนจะ deploy จดหมายข่าว APIs You Won’t Hate ระบุว่า web framework หลายตัวจัดการ QUERY ได้โดยตรงอยู่แล้ว หรือผ่าน custom-method routing
วิธีนำ QUERY มาใช้โดยไม่ทำให้ client พัง
คุณไม่จำเป็นต้องรื้อ POST search endpoint เดิมออก
- เพิ่ม QUERY ควบคู่ไปกับ route POST ให้ทั้งคู่ชี้ไปที่ handler เดียวกัน client ใหม่ใช้ QUERY ส่วนตัวเก่ายังทำงานได้
- ประกาศให้รู้ ส่ง
Accept-Queryกับ resource และใส่QUERYในAllowของ responseOPTIONSและ405 - บังคับใช้ Content-Type ส่ง 400 หรือ 415 ตามที่ RFC แนะนำ และ 422 สำหรับ query ที่ parse ได้แต่รันไม่ได้
- fallback ด้วย 405 หรือ 501 client ควร retry body เดิมเป็น POST เมื่อมีจุดใดจุดหนึ่งในเส้นทางปฏิเสธ QUERY
- แก้ CORS เพิ่ม
QUERYในAccess-Control-Allow-Methodsสำหรับ client ที่เป็นเบราว์เซอร์ - ตัดสินใจเรื่อง caching เปิด shared caching เฉพาะที่ cache ของคุณ key ด้วย body เท่านั้น มิฉะนั้นให้ส่ง URI ใน
Locationแล้วให้ client GET มัน - เขียนเอกสารกำกับ ใน OpenAPI 3.2 ให้ define operation ใต้
query:ของ path item:
openapi: 3.2.0
paths:
/products:
query:
summary: Search products
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ProductQuery'
responses:
'200':
description: Matching products
filter สั้น ๆ ง่าย ๆ ยังใช้เป็น query string บน GET ได้เหมือนเดิม RFC 10008 เองก็บอกว่าถ้า query ของคุณสั้นขนาดนั้น GET น่าจะเป็นทางเลือกที่ดีกว่า
ให้ coding agent ของคุณทดสอบ QUERY endpoint ด้วย Apidog CLI
method ใหม่หมายถึงต้องเช็คทั้ง happy path, error code ทุกตัว และ fallback route มอบงานนี้ให้ Claude Code, Codex หรือ Cursor แล้วให้มันขับเคลื่อน Apidog CLI
ติดตั้ง CLI, ล็อกอิน และเพิ่ม skill ของ Apidog ให้ agent ของคุณ:
npm install -g apidog-cli@latest
apidog login --with-token <YOUR_TOKEN>
npx -y skills add https://apidog.com # pick your agent when prompted
จากนั้นให้ prompt หนึ่งข้อกับ agent ของคุณ:
In Apidog project <projectId>, add a QUERY /products endpoint that takes a
JSON body {q, limit}. Create test cases that assert 200 with an array for a
valid body, 415 for Content-Type text/plain, and 400 with no Content-Type.
Run them against the staging environment and summarize any failures.
agent จะอ่าน schema แต่ละตัว, validate payload ของมัน แล้วจึงเขียน:
apidog cli-schema get endpoint-create
apidog cli-schema validate endpoint-create --file endpoint.json
apidog endpoint create --project <projectId> --file endpoint.json
apidog cli-schema get test-case-create
apidog cli-schema validate test-case-create --file case.json
apidog test-case create --project <projectId> --file case.json
apidog run --test-case <caseId> --project <projectId> -e <envId> -r cli,json
endpoint.json ที่มันเขียนจะตั้ง "method": "query" ซึ่ง schema endpoint-create ของ CLI ระบุไว้เคียงข้าง get, post และ method ต่าง ๆ ของ WebDAV เพิ่ม --upload-report เพื่อดูผลการรันในแอป Apidog คำสั่ง apidog run เดียวกันพร้อม -r junit ก็ใช้ใน CI ได้เลย ดู วิธีรัน API test ใน CI ด้วย apidog run และ วิธีใช้ Apidog CLI ใน Claude Code แพลนฟรีของ Apidog รองรับผู้ใช้สูงสุด 4 คน
คำถามที่พบบ่อย
HTTP QUERY method เป็นมาตรฐานอย่างเป็นทางการแล้วหรือยัง? ใช่แล้ว RFC 10008 เป็น RFC ประเภท Standards Track, Proposed Standard ที่เผยแพร่เมื่อมิถุนายน 2026 และ IANA ระบุ QUERY ไว้ใน HTTP Method Registry ว่า safe และ idempotent
QUERY เป็นแค่ GET ที่มี body ใช่ไหม? ใกล้เคียง แต่ถูกนิยามไว้ดีกว่า RFC 9110 ไม่ให้นิยามความหมายใด ๆ กับ body ของ GET ดังนั้นตัวกลางต่าง ๆ จึงเพิกเฉยหรือปฏิเสธมันได้ QUERY ทำให้ body เป็นตัว query, บังคับให้มี Content-Type และรวม body เข้าเป็นส่วนหนึ่งของ cache key
ควรใช้ QUERY แทน POST เมื่อไหร่? ใช้ QUERY สำหรับการค้นหาหรือ filter แบบอ่านอย่างเดียวใด ๆ ที่ใหญ่เกินไปหรืออ่อนไหวเกินไปสำหรับ URL ส่วน POST ให้เก็บไว้สำหรับ request ที่สร้างหรือเปลี่ยนแปลงบางอย่าง
เบราว์เซอร์ส่ง QUERY request ได้ไหม? ได้ ผ่าน fetch ด้วย custom method request แบบ QUERY ข้ามโดเมนต้องมี CORS preflight เสมอ ดังนั้นเซิร์ฟเวอร์ของคุณต้องอนุญาต method นี้
response ของ QUERY ถูก cache ไหม? สามารถ cache ได้ cache ต้องรวม request body และ metadata ของมันไว้ใน cache key CDN และ proxy หลายเจ้ายังไม่ทำแบบนี้ ดังนั้นควรตรวจสอบของตัวเอง หรือส่ง URI ใน Location ที่ client GET ได้
OpenAPI รองรับ QUERY ไหม? OpenAPI 3.2 เพิ่ม field query ใน Path Item Object สำหรับ operation แบบ QUERY ดังนั้นคุณเขียนเอกสารกำกับได้โดยไม่ต้องใช้ extension
