Go 1.27 รับรอง QUERY — HTTP Method ใหม่ที่ GET ทำไม่ได้

go dev.to

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
Enter fullscreen mode Exit fullscreen mode

พารามิเตอร์เยอะมากจน 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"]}}
Enter fullscreen mode Exit fullscreen mode
คุณสมบัติ 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
Enter fullscreen mode Exit fullscreen mode

QUERY ส่ง body แทน:

QUERY /api/search
Content-Type: application/json
{"q": "golang", "tags": ["programming", "language", "backend"], ...}
Enter fullscreen mode Exit fullscreen mode

ปัญหาที่ 2: ข้อมูล sensitive ใน URL

GET /api/search?email=user@example.com&ssn=1234
→ URL ถูก log โดย proxy, server, CDN — SSN รั่ว!
Enter fullscreen mode Exit fullscreen mode

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"}}]}}
Enter fullscreen mode Exit fullscreen mode

การมี QUERY เปลี่ยนอะไร

ก่อน QUERY — ทางเลือกที่มี

1. GET + query string → URL ยาว, sensitive data รั่ว
2. POST + body → ใช้ได้ แต่ผิด semantics → ไม่ cache, SEO ไม่ดี
3. POST + body + X-HTTP-Method-Override → workaround แต่ไม่ standard
Enter fullscreen mode Exit fullscreen mode

หลัง QUERY — ทางเลือกใหม่

QUERY /api/search → body = query → safe, cacheable, clean
Enter fullscreen mode Exit fullscreen mode

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)
}
Enter fullscreen mode Exit fullscreen mode

ก่อน 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)
Enter fullscreen mode Exit fullscreen mode

ประโยชน์:

  • ✅ 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)
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

ถ้าคุณเป็น 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)
});
Enter fullscreen mode Exit fullscreen mode

ถ้าคุณเป็น DevOps / Infrastructure

  • CDN: อัปเดต config ให้ cache QUERY requests
  • Proxy/Load Balancer: เช็คว่ารองรับ QUERY method หรือไม่ (บางตัวอาจ reject)
  • Logging/Monitoring: เพิ่ม QUERY ใน metrics
  • WAF/Firewall: allow QUERY method

สถานะปัจจุบัน

RFC 9110:        ✅ Published (June 2022)
Browser support: ⚠️ fetch() รองรับ แต่ยังไม่ widespread
Go support:      🚧 Go 1.27 (August 2026) — ในระหว่างพัฒนา
GitHub Issue:    #80134 (darkweak, opened June 2026)
Enter fullscreen mode Exit fullscreen mode

สรุป

QUERY คือ GET ที่มี body — safe, idempotent, cacheable — ออกแบบมาสำหรับ search และ query ที่ซับซ้อน

Go 1.27 เป็น milestone สำคัญที่ทำให้ QUERY กลายเป็น first-class citizen ใน ecosystem — หลังจากนี้ เราน่าจะเห็น API เปลี่ยนจาก POST /search เป็น QUERY /search มากขึ้น

📚 อ่านต่อ:

📅 เขียนเมื่อ: กรกฎาคม 2026 | Go 1.27 อยู่ในระหว่างพัฒนา

Source: dev.to

arrow_back Back to Tutorials