Go 1.27 รับรอง QUERY — HTTP Method ใหม่ที่ GET ทำไม่ได้
⚠️ Go 1.27 ยังไม่ release — คาดเดือนสิงหาคม 2026 — QUERY method อยู่ในระหว่าง development (issue #80134)
ถ้าคุณเคยเขียน search API — คุณน่าจะเคยเจอปัญหานี้:
GET /api/search?q=golang&category=book&year=2025&author=donovan
พารามิเตอร์เยอะมากจน URL ยาวเป็นหางว่าว — แล้วยิ่งถ้าต้องส่ง query ที่ซับซ้อน (nested conditions, OR, range queries) — GET แทบจะใช้งานไม่ได้
แล้วก็มีคนเสนอว่า: "งั้นใช้ POST สิ" — แต่ POST ไม่ใช่ safe method — มันไม่ควร cache, search engine ไม่ index, CDN ไม่ cache
ทางออกที่วงการ HTTP ออกแบบมาตั้งแต่ปี 2022: QUERY method
และตอนนี้ Go 1.27 กำลังจะรับรองมันอย่างเป็นทางการ
QUERY คืออะไร
QUERY คือ HTTP method ที่ถูกกำหนดใน RFC 9110 (HTTP Semantics, มิถุนายน 2022)
QUERY /api/search HTTP/1.1
Content-Type: application/json
{"q":"golang","category":"book","year":2025,"filters":{"price":{"gte":20,"lte":50},"language":["en","th"]}}
| คุณสมบัติ | GET | POST | QUERY |
|---|---|---|---|
| Safe (ไม่เปลี่ยน state) | ✅ | ❌ | ✅ |
| Idempotent (เรียกซ้ำได้ผลลัพธ์เดิม) | ✅ | ❌ | ✅ |
| มี request body ได้ | ❌ (ทำได้แต่ไม่ควร) | ✅ | ✅ |
| Cache ได้ | ✅ | ❌ | ✅ |
| Search engine index | ✅ | ❌ | ✅ |
QUERY = GET + request body — ปลอดภัย, cache ได้, ส่ง query ซับซ้อนได้
ทำไมถึงต้องมี QUERY — ปัญหาที่ GET แก้ไม่ได้
ปัญหาที่ 1: URL ยาวเกิน
GET /api/search?q=golang&tags=programming,language,backend&...
→ URL 500+ ตัวอักษร — หลาย browser/proxy มี limit ที่ 2,048
QUERY ส่ง body แทน:
QUERY /api/search
Content-Type: application/json
{"q": "golang", "tags": ["programming", "language", "backend"], ...}
ปัญหาที่ 2: ข้อมูล sensitive ใน URL
GET /api/search?email=user@example.com&ssn=1234
→ URL ถูก log โดย proxy, server, CDN — SSN รั่ว!
QUERY: ข้อมูลอยู่ใน body — ไม่ปรากฏใน log
ปัญหาที่ 3: Query ซับซ้อนเกิน query string
#Elasticsearch-stylequery—เขียนในquerystringไม่ได้{"bool":{"must":[{"term":{"status":"active"}},{"range":{"created_at":{"gte":"2025-01-01"}}}],"should":[{"match":{"title":"golang"}},{"match":{"description":"go programming"}}]}}
การมี QUERY เปลี่ยนอะไร
ก่อน QUERY — ทางเลือกที่มี
1. GET + query string → URL ยาว, sensitive data รั่ว
2. POST + body → ใช้ได้ แต่ผิด semantics → ไม่ cache, SEO ไม่ดี
3. POST + body + X-HTTP-Method-Override → workaround แต่ไม่ standard
หลัง QUERY — ทางเลือกใหม่
QUERY /api/search → body = query → safe, cacheable, clean
Go 1.27 — วิธีใช้
package main
import (
"fmt"
"net/http"
)
func searchHandler(w http.ResponseWriter, r *http.Request) {
// Go 1.27 — ใช้ MethodQuery แทน string "QUERY"
if r.Method != http.MethodQuery {
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
return
}
// อ่าน request body — เหมือน POST
var query SearchQuery
json.NewDecoder(r.Body).Decode(&query)
results := search(query)
json.NewEncoder(w).Encode(results)
}
func main() {
http.HandleFunc("QUERY /api/search", searchHandler)
http.ListenAndServe(":8080", nil)
}
ก่อน Go 1.27: ต้องใช้ string "QUERY" ตรง ๆ — http.MethodQuery ยังไม่มี
Go 1.27: เพิ่ม http.MethodQuery — constant มาตรฐาน เหมือน http.MethodGet, http.MethodPost
คนทำงานควรปรับตัวอย่างไร
ถ้าคุณเป็น Backend Developer
1. ใช้ QUERY สำหรับ search endpoint
- r.HandleFunc("POST /api/search", searchHandler)
+ r.HandleFunc("QUERY /api/search", searchHandler)
ประโยชน์:
- ✅ CDN cache ได้ — ลด load server
- ✅ Semantics ถูกต้อง — POST ไม่ใช่วิธีที่ถูกสำหรับการ search
- ✅ API ของคุณ self-documenting —
QUERYบอกว่า "นี่คือการอ่านข้อมูล"
2. อัปเดต API documentation
Old: POST /api/search (ใช้ POST เพราะ query ซับซ้อนเกิน GET)
New: QUERY /api/search (ใช้ QUERY — safe, cacheable)
3. รองรับทั้งสองวิธีในช่วงเปลี่ยนผ่าน
func searchHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodQuery && r.Method != http.MethodPost {
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
return
}
// ... logic
}
ถ้าคุณเป็น Frontend Developer
// จาก POST
const res = await fetch("/api/search", {
method: "POST",
body: JSON.stringify(query)
});
// เป็น QUERY
const res = await fetch("/api/search", {
method: "QUERY",
body: JSON.stringify(query)
});
ถ้าคุณเป็น DevOps / Infrastructure
-
CDN: อัปเดต config ให้ cache
QUERYrequests -
Proxy/Load Balancer: เช็คว่ารองรับ
QUERYmethod หรือไม่ (บางตัวอาจ reject) -
Logging/Monitoring: เพิ่ม
QUERYใน metrics -
WAF/Firewall: allow
QUERYmethod
สถานะปัจจุบัน
RFC 9110: ✅ Published (June 2022)
Browser support: ⚠️ fetch() รองรับ แต่ยังไม่ widespread
Go support: 🚧 Go 1.27 (August 2026) — ในระหว่างพัฒนา
GitHub Issue: #80134 (darkweak, opened June 2026)
สรุป
QUERY คือ GET ที่มี body — safe, idempotent, cacheable — ออกแบบมาสำหรับ search และ query ที่ซับซ้อน
Go 1.27 เป็น milestone สำคัญที่ทำให้ QUERY กลายเป็น first-class citizen ใน ecosystem — หลังจากนี้ เราน่าจะเห็น API เปลี่ยนจาก POST /search เป็น QUERY /search มากขึ้น
📚 อ่านต่อ:
- RFC 9110: HTTP Semantics — QUERY method definition
- Go Issue #80134 — net/http: add QUERY HTTP method
- Go Issue #80058 — proposal: MethodQuery constant
- Go 1.27 Release Notes — draft
📅 เขียนเมื่อ: กรกฎาคม 2026 | Go 1.27 อยู่ในระหว่างพัฒนา