เมธอด HTTP QUERY ใหม่
(kreya.app)คำอธิบายเกี่ยวกับเมธอด HTTP QUERY ที่เพิ่งนิยามขึ้นใหม่ใน RFC 10008
ใน RESTful API เดิม เมื่อจัดการการค้นหาที่ซับซ้อน ทั้ง GET และ POST ต่างก็มีข้อจำกัด และหลังจากการถกเถียงกันมายาวนาน เมธอด QUERY จึงถูกทำให้เป็นมาตรฐานเพื่อแก้ปัญหานี้
ข้อจำกัดของ GET
- หากส่งตัวกรองที่ซับซ้อนหรือ relational query ผ่านพารามิเตอร์ URL จะทำให้ URL ยาวเกินไป และอาจชนกับข้อจำกัดจำนวนอักขระของเบราว์เซอร์หรือเซิร์ฟเวอร์
- อักขระที่ไม่ใช่ ASCII หรืออักขระพิเศษต้องมีการ encode ทำให้ขนาดคำขอเพิ่มขึ้น
- วิธีแสดง array หรือโครงสร้างซ้อนยังไม่ได้ถูกทำให้เป็นมาตรฐาน (เช่น roles[]=admin vs roles=admin)
- เซิร์ฟเวอร์/มิดเดิลแวร์บันทึกพารามิเตอร์ URL ลง log จึงเป็นปัญหาเมื่อส่งข้อมูลอ่อนไหว
- การส่ง request body กับ GET ไม่ได้ถูกห้ามอย่างชัดเจนตามสเปก แต่ proxy/firewall/เบราว์เซอร์แต่ละตัวจัดการต่างกัน จึงใช้งานจริงแทบไม่ได้
ปัญหาของการใช้ POST เลี่ยง
- แม้จะส่ง request body ได้ แต่ POST ถูกนิยามว่าเป็น non-idempotent จึงไม่ปลอดภัยสำหรับการ retry อัตโนมัติเมื่อเกิดความล้มเหลว
- proxy หรือมิดเดิลแวร์ไม่สามารถรับรู้ได้ว่าเป็นงานแบบ read-only ทำให้ทำ optimization อย่างการ caching อัตโนมัติไม่ได้
- ในเชิง semantic การใช้ POST ซึ่งมีไว้สำหรับการสร้าง/ประมวลผล resource กับการค้นหา ไม่สอดคล้องกับหลักการออกแบบ RESTful
เมธอด QUERY
- เมธอด HTTP ใหม่ที่ safe และ idempotent เหมือน GET พร้อมทั้งสามารถมี request body ได้
- สามารถ cache ได้ แต่เมื่อนำไป implement ต้องรวม request body ไว้ใน cache key ด้วย จึงทำให้การ implement caching ซับซ้อนกว่า GET
- สรุปคือเป้าหมายหลักคือ “แทนที่ POST ในคำขอแบบ read-only”
ข้อควรระวัง
- การรองรับ QUERY ของ client/proxy/server ยังมีจำกัด และอาจต้องใช้เวลากว่าจะรองรับอย่างสมบูรณ์
- หากพารามิเตอร์ query ของ GET แบบเรียบง่ายเพียงพอ ก็ไม่จำเป็นต้องเปลี่ยน
- หากจำเป็นต้องแชร์ URL หรือ bookmark ข้อมูลที่ผ่านการกรองแล้ว GET ก็ยังเหมาะสม
6 ความคิดเห็น
เอ่อ... เขาไม่ได้คิดกันบ้างเหรอว่าอีกสัก 10 ปีข้างหน้า QUERY method ก็อาจจะยังไม่ถูกนำไปใช้ใน proxy/firewall/browser แต่ละตัวอยู่ดี? หรือว่ามองไกลกันมากจริง ๆ?
น่าจะเป็นอย่างหลังนะ
จำได้ว่าเคยมีปัญหาที่ service API ของบริษัทแห่งหนึ่งรับ
POSTแต่ถ้าไม่ส่ง URL parameter แบบเดียวกันมาด้วยก็จะไม่ทำงานในเกาหลีเองก็ยังมีหลายกรณีที่พอเป็น
PUTหรือDELETEแล้วคนจะงงว่า นี่คืออะไร? เลยไม่รู้ว่าถ้าจะให้QUERYแพร่หลายจริง ๆ จะต้องใช้เวลาอีกนานแค่ไหน???: POST ดีต่อความปลอดภัย
??? : อย่ามัวแต่ทำให้เป็น REST เลย ใช้ POST ให้เหมือนกันทั้งหมดก็พอ
เอกสาร RFC คือ https://datatracker.ietf.org/doc/rfc10008/ นะครับ
GET มีข้อเสียตรงที่ URL จะยาวขึ้น แต่ก็ดูเหมือนจะมีข้อดีตรงที่สามารถแชร์ที่อยู่ URL ได้ตรง ๆ เช่น เวลาที่อยากแชร์ผลลัพธ์ของฟิลเตอร์การค้นหาเฉพาะใน ElasticSearch
มีหลายจุดที่น่าจะใช้งาน GET กันแบบโดยนัยภายใต้สมมติฐานว่าคำขอจะถูกพิมพ์ลงในแถบที่อยู่ของเบราว์เซอร์ ดังนั้นกว่าจะตั้งหลักได้ก็คงต้องใช้เวลาอีกมาก นอกเหนือไปจากการรองรับทางเทคนิค