1 คะแนน โดย GN⁺ 4 시간 전 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • RFC 10008 กำหนด HTTP เมธอด QUERY สำหรับให้ทรัพยากรเป้าหมายประมวลผลคำสืบค้นที่อยู่ในเนื้อหาคำขอแบบ ปลอดภัยและมีความเป็นไอดีมโพเทนต์ แล้วส่งคืนผลลัพธ์
  • QUERY ผสานคุณสมบัติ safe/idempotent ของ GET เข้ากับการส่งเนื้อหาแบบ POST เพื่อช่วยลดปัญหา URI ยาว ค่าใช้จ่ายของการเข้ารหัส URI การเผยข้อมูลในล็อก และภาระในการทำให้ชุดคำสืบค้นแต่ละแบบกลายเป็นทรัพยากร
  • เซิร์ฟเวอร์จะประมวลผลคำขอ QUERY ได้ก็ต่อเมื่อ Content-Type และเนื้อหาคำขอสอดคล้องกัน โดยชนิดที่ไม่รองรับ เนื้อหาไม่ตรงกัน และคำสืบค้นที่ประมวลผลไม่ได้ สามารถแยกตอบด้วยสถานะ 4xx ที่ต่างกันได้
  • การตอบกลับที่สำเร็จสามารถใช้ Content-Location เพื่อระบุทรัพยากรผลลัพธ์ของคำสืบค้น และใช้ Location เพื่อระบุ equivalent resource ที่ใช้เรียกคำสืบค้นเดิมซ้ำได้
  • การตอบกลับของ QUERY สามารถแคชได้ แต่คีย์แคชต้องรวมถึงเนื้อหาและเมทาดาทาด้วย และในสภาพแวดล้อม CORS ต้องมี preflight เพราะไม่ใช่ safelisted method

รูปแบบคำสืบค้น HTTP ที่ QUERY ต้องการแก้ไข

  • RFC 10008 เป็นเอกสาร Internet Standards Track ที่กำหนด เมธอดคำขอ QUERY ของ HTTP
  • QUERY ใช้เพื่อขอให้ทรัพยากรเป้าหมายประมวลผลเนื้อหาคำขอแล้วตอบกลับผลลัพธ์
  • แม้จะใช้เนื้อหาแบบเดียวกับ POST แต่ถูกกำหนดให้เป็น safe และ idempotent จึงสามารถรีทรายอัตโนมัติหรือเริ่มใหม่ได้
  • เดิมคำสืบค้นแบบ GET มักใส่อินพุตไว้ใน URI
    • GET /feed?q=foo&limit=10&sort=-published HTTP/1.1
  • เมื่อใส่ข้อมูลคำสืบค้นไว้ใน URI ข้อจำกัดจะเพิ่มขึ้นตามขนาดข้อมูล
    • เพราะต้องผ่านหลายระบบอิสระ จึงยากที่จะรู้ขีดจำกัดขนาด URI ที่แท้จริงล่วงหน้า
    • HTTP แนะนำให้ทั้งผู้ส่งและผู้รับรองรับอย่างน้อย 8000 octets แต่ไม่ได้รับประกันว่าทุกระบบระหว่างทางจะรองรับ
    • ข้อมูลบางประเภทมีต้นทุนสูงในการเข้ารหัสให้เป็น URI ที่ถูกต้อง
    • URI ของคำขอมักถูกบันทึกลงล็อกหรือรวมอยู่ในบุ๊กมาร์กได้มากกว่าเนื้อหาคำขอ
    • หากเข้ารหัสคำสืบค้นลงใน URI โดยตรง ชุดอินพุตที่เป็นไปได้แต่ละแบบจะถูกมองเป็นทรัพยากรแยกกัน

เมธอดที่ทำให้ความหมายระหว่าง GET กับ POST ชัดเจนขึ้น

  • หลายการใช้งานส่งคำสืบค้นผ่านเนื้อหา POST แทน GET
    • POST /feed
    • Content-Type: application/x-www-form-urlencoded
    • เนื้อหา: q=foo&limit=10&sort=-published
  • วิธีนี้ไม่บอกชัดว่าคำสืบค้นนั้นปลอดภัยและมีความเป็นไอดีมโพเทนต์หรือไม่ หากไม่รู้จักทรัพยากรและเซิร์ฟเวอร์นั้นเป็นพิเศษ
  • QUERY ส่งอินพุตแบบเดียวกันผ่านเนื้อหาคำขอ แต่ตัวเมธอดเองมีความเป็น safe และ idempotent
    • QUERY /feed
    • Content-Type: application/x-www-form-urlencoded
    • เนื้อหา: q=foo&limit=10&sort=-published
  • ความหมายที่ชัดเจนนี้ทำให้นำความสามารถของ HTTP เช่นการแคชและการรีทรายอัตโนมัติมาใช้ได้ง่ายขึ้น
  • เซิร์ฟเวอร์สามารถกำหนด URI ให้กับตัวคำสืบค้นเองหรือผลลัพธ์ของคำสืบค้น เพื่อให้เรียกด้วย GET ภายหลังได้

กฎหลักของเมธอด QUERY

  • QUERY ใช้เพื่อเริ่มต้นคำสืบค้นฝั่งเซิร์ฟเวอร์
  • GET ขอ representation ของทรัพยากรที่ URI เป้าหมายระบุไว้ ส่วน QUERY ขอให้ดำเนินการ งานคำสืบค้น ภายในขอบเขตของทรัพยากรเป้าหมาย
  • เนื้อหาคำขอและมีเดียไทป์เป็นตัวกำหนดคำสืบค้น ส่วน origin server เป็นผู้กำหนดขอบเขตงานโดยอิงจากทรัพยากรเป้าหมาย
  • หากไม่มีฟิลด์คำขอ Content-Type หรือไม่สอดคล้องกับเนื้อหาคำขอ เซิร์ฟเวอร์ต้องทำให้คำขอล้มเหลว
  • query part ของ URI เป้าหมายยังคงมีส่วนในการระบุทรัพยากรเป้าหมาย เช่นเดียวกับเมธอด HTTP อื่นทั้งหมด
    • ส่วน query นั้นมีผลต่อผลลัพธ์โดยตรงหรืออย่างไร เป็นพฤติกรรมเฉพาะของทรัพยากรและอยู่นอกขอบเขตของสเปกนี้
  • QUERY มีความเป็น safe จากมุมมองของทรัพยากรเป้าหมาย
    • ไคลเอนต์ไม่ได้ร้องขอหรือคาดหวังให้สถานะของทรัพยากรเป้าหมายเปลี่ยนแปลง
    • เซิร์ฟเวอร์ยังสามารถสร้างทรัพยากร HTTP สำหรับดูข้อมูลเพิ่มเติมได้ โดยไม่ได้ถูกห้าม
  • QUERY เป็น idempotent จึงสามารถส่งซ้ำหรือรีทรายได้เมื่อจำเป็นหลังการเชื่อมต่อล้มเหลว
  • การตอบกลับ 200 OK หมายถึงคำสืบค้นถูกประมวลผลสำเร็จและผลลัพธ์อยู่ในเนื้อหาการตอบกลับ

มีเดียไทป์ การเจรจา และการจัดการข้อผิดพลาด

  • ความหมายของคำขอ QUERY ขึ้นอยู่กับเนื้อหาคำขอและเมทาดาทาที่เกี่ยวข้อง เช่น มีเดียไทป์
  • คำขอที่เนื้อหาและเมทาดาทาไม่สอดคล้องกัน โดยทั่วไปควรถูกปฏิเสธด้วย 4xx Client Error
  • การจัดการข้อผิดพลาดแตกต่างกันไปตามจุดที่คำขอผิดพลาด
    • หากไม่มีข้อมูลมีเดียไทป์ คำขอนั้นผิดตามนิยาม จึงควรล้มเหลวด้วยสถานะ 4xx เช่น 400
    • หากระบุมีเดียไทป์แล้วแต่ทรัพยากรไม่รองรับ 415 Unsupported Media Type เหมาะสมกว่า
    • แม้มีเดียไทป์นั้นจะเป็นที่รู้จักโดยหลักการ แต่ถ้าไม่มีความหมาย QUERY สำหรับทรัพยากรเป้าหมาย ก็อาจเข้าข่าย 415 ได้เช่นกัน
    • หากมีเดียไทป์ไม่ตรงกับเนื้อหาคำขอจริง สามารถตอบ 400 Bad Request ได้
    • เซิร์ฟเวอร์ต้องไม่ทำ content sniffing โดยเดามีเดียไทป์จากเนื้อหาเพื่อแทนค่าที่หายไปหรือผิด
    • หากชนิดและเนื้อหาตรงกัน แต่ตัวคำสืบค้นจริงไม่สามารถประมวลผลได้ อาจใช้ 422 Unprocessable Content
    • ตัวอย่างของ 422 คือคำสั่ง SQL ที่ถูกต้องตามไวยากรณ์ แต่ชี้ไปยังตารางที่ไม่มีอยู่จริง
    • หากทรัพยากรไม่รองรับมีเดียไทป์การตอบกลับที่ไคลเอนต์ร้องขอผ่าน Accept ควรใช้ 406 Not Acceptable
  • ฟิลด์ตอบกลับ Accept-Query สามารถใช้บอกไคลเอนต์ว่ารองรับมีเดียไทป์คำสืบค้นใดบ้าง

equivalent resource, Content-Location, Location

  • equivalent resource คือทรัพยากรที่แทนคำขอ QUERY รายการหนึ่งพร้อมเป้าหมายของมัน และตอบสนองต่อคำขอ GET ได้
  • equivalent resource พิจารณาทั้งเนื้อหาคำขอและเมทาดาทา
    • รวมถึง representation metadata เช่นมีเดียไทป์ของเนื้อหา
  • เซิร์ฟเวอร์อาจกำหนด URI ให้กับ equivalent resource ได้ แต่ไม่จำเป็น
  • การตอบกลับที่สำเร็จสามารถใส่ตัวระบุทรัพยากรของผลลัพธ์คำสืบค้นไว้ในเฮดเดอร์ Content-Location
    • ไคลเอนต์สามารถส่ง GET ไปยัง URI ที่ระบุเพื่อดึงผลของงานคำสืบค้นที่เพิ่งทำไป
    • ทรัพยากรนั้นอาจเป็นแบบชั่วคราว
  • การตอบกลับที่สำเร็จสามารถใส่ URI ของ equivalent resource ของคำขอ QUERY ไว้ในเฮดเดอร์ Location
    • ไคลเอนต์สามารถส่ง GET ไปยัง URI ที่ระบุเพื่อทำคำสืบค้นเดิมซ้ำ โดยไม่ต้องส่งเนื้อหาคำสืบค้นอีกครั้ง
    • URI นี้ก็อาจเป็นแบบชั่วคราวได้เช่นกัน
    • หากคำขอภายหลังล้มเหลว ไคลเอนต์สามารถลองใหม่โดยใช้เป้าหมาย QUERY เดิมและเนื้อหาที่เคยส่งไปก่อนหน้า

การเปลี่ยนเส้นทางและคำขอแบบมีเงื่อนไข

  • เซิร์ฟเวอร์สามารถเลือกตอบแบบอ้อมด้วยการเปลี่ยนเส้นทาง user agent ของคำขอ QUERY ไปยัง URI อื่นได้
  • 301 Moved Permanently และ 308 Permanent Redirect แสดงว่าทรัพยากรเป้าหมายถูกย้ายถาวรไปยัง URI อื่นที่ Location ชี้ไว้
  • 302 Found และ 307 Temporary Redirect หมายถึงการย้ายชั่วคราวของทรัพยากรเป้าหมาย
  • ในทั้งสี่กรณี เซิร์ฟเวอร์เสนอว่าคำขอเดิมสามารถทำได้โดยส่ง คำขอ QUERY ที่คล้ายกันไปยัง URI เป้าหมายใหม่
  • ข้อยกเว้นที่ให้เปลี่ยนเส้นทาง POST เป็น GET หลัง 301 หรือ 302 ไม่ใช้กับคำขอ QUERY
  • 303 See Other สำหรับ QUERY หมายถึงสามารถทำคำสืบค้นเดิมเป็นคำขอดึงข้อมูลปกติไปยัง URI ที่ Location ชี้ไว้
    • ใน HTTP จะส่งคำขอ GET ไปยัง URI เป้าหมายใหม่
  • ใน QUERY แบบมีเงื่อนไข selected representation จะเท่ากับ GET ของ equivalent resource สำหรับคำขอ QUERY นั้น
  • ไคลเอนต์สามารถขอให้ส่งคืนผลลัพธ์คำสืบค้นเฉพาะเมื่อเงื่อนไขที่ระบุใน conditional header เป็นจริง

การแคชและคำขอ Range

  • การตอบกลับของเมธอด QUERY สามารถแคชได้ และแคชสามารถใช้ตอบคำขอ QUERY ครั้งถัดไปได้
  • คีย์แคช ของคำขอ QUERY ต้องรวมเนื้อหาคำขอและเมทาดาทาที่เกี่ยวข้อง
  • แคชสามารถตัดความแตกต่างที่ไม่สำคัญทางความหมายออกเพื่อสร้างคีย์แคชได้
    • ลบ content encoding
    • ทำ normalization ตามธรรมเนียมรูปแบบที่ media subtype suffix อย่าง +json สื่อไว้
    • ทำ normalization ตามความหมายของเนื้อหาที่ Content-Type ระบุไว้
  • การแปลงเหล่านี้มีไว้เพื่อสร้างคีย์แคชเท่านั้น และไม่ได้เปลี่ยนคำขอจริง
  • ไคลเอนต์สามารถระบุผ่าน cache directive no-transform ว่าไม่ต้องการการแปลงดังกล่าวได้ แต่คำสั่งนี้เป็นเพียง advisory
  • การแคชการตอบกลับของ QUERY ซับซ้อนกว่า GET โดยธรรมชาติ
    • ต้องอ่านเนื้อหาคำขอทั้งหมดก่อนจึงจะกำหนดคีย์แคชได้
    • หากการตอบกลับของ QUERY ให้ URI ของ equivalent resource ผ่าน Location ไคลเอนต์สามารถเปลี่ยนไปใช้ GET ในภายหลังเพื่อทำให้การประมวลผลง่ายขึ้น
  • ความหมายของ Range Request สำหรับ QUERY เหมือนกับ GET
  • Byte Range Request ซึ่งเป็น range unit เดียวที่กำหนดไว้ ณ เวลาที่เขียน มีประโยชน์กับผลลัพธ์ QUERY ค่อนข้างน้อย
  • รูปแบบคำสืบค้นเองมักมีความสามารถจำกัดผลลัพธ์หรือแบ่งหน้าอยู่แล้ว เช่น FETCH FIRST ... ROWS ONLY ของ SQL และคาดว่าจะใช้ความสามารถในตัวเหล่านี้

เฮดเดอร์ตอบกลับ Accept-Query

  • เฮดเดอร์ตอบกลับ Accept-Query ใช้บอกโดยตรงว่าทรัพยากรรองรับเมธอด QUERY และระบุมีเดียไทป์ของรูปแบบคำสืบค้นที่ใช้ได้
  • Accept-Query เป็นรายการ media range ที่ใช้ไวยากรณ์ Structured Fields
  • media range แสดงเป็น List Structured Header Field ของ Token หรือ String ที่เก็บค่า media range โดยไม่มีพารามิเตอร์
  • พารามิเตอร์ของมีเดียไทป์จะถูกแมปเป็น Structured Field Parameters
    • การเลือกใช้ String หรือ Token ไม่มีความสำคัญเชิงความหมาย
    • ผู้รับสามารถแปลง Token เป็น String ได้ แต่ต้องไม่ปฏิบัติต่างกันตามชนิดที่ได้รับ
  • มีเดียไทป์ไม่ได้แมปกับ Token อย่างตรงตัว และกรณีที่อนุญาตตัวเลขนำหน้า ต้องใช้รูปแบบ String
  • wildcard ที่รองรับมีเพียง */* หรือ xxxx/*
  • ลำดับของชนิดที่แสดงในค่าฟิลด์ไม่มีความสำคัญ
  • ค่า Accept-Query ใช้กับทุก URI ของเซิร์ฟเวอร์ที่ใช้ path เดียวกัน โดยไม่สนใจ query component
  • หากคำขอของทรัพยากรเดียวกันส่งคืนค่า Accept-Query ต่างกัน ให้ใช้ค่าที่ fresh ล่าสุดที่ได้รับ
  • ตัวอย่างมีดังนี้
    • Accept-Query: "application/jsonpath", application/sql;charset="UTF-8"
  • แม้ Accept-Query จะดูคล้าย Accept แต่เป็น Structured Field จึงต้องปฏิบัติตามกฎการประมวลผล Structured Fields ของ RFC 9651

ข้อพิจารณาด้านความปลอดภัยและ CORS

  • QUERY ปฏิบัติตามข้อพิจารณาด้านความปลอดภัยทั่วไปของเมธอด HTTP ทั้งหมดที่กำหนดไว้ใน RFC 9110
  • QUERY สามารถใช้เป็นทางเลือกแทนการใส่ข้อมูลคำขอไว้ใน URI query component ได้
  • เนื่องจาก URI มีแนวโน้มถูกบันทึกลงล็อกหรือถูกตัวกลางประมวลผลมากกว่าเนื้อหาคำขอ QUERY จึงอาจเหมาะกว่า GET สำหรับคำสืบค้นที่มีข้อมูลอ่อนไหว
  • เมื่อเซิร์ฟเวอร์สร้างทรัพยากรชั่วคราวแทนผลลัพธ์ QUERY และกำหนด URI ให้ หากเนื้อหาคำขอเดิมมีข้อมูลอ่อนไหวที่ไม่ควรถูกบันทึกลงล็อก ก็ไม่ควรใส่ส่วนนั้นไว้ใน URI
  • หากแคชทำ normalization ของเนื้อหา QUERY ผิด หรือแตกต่างจากวิธีประมวลผลของทรัพยากรมากเกินไป อาจเกิด false positive แล้วส่งคืนคำตอบที่ผิดได้
  • คำขอ QUERY จาก user agent ที่ใช้ CORS ต้องมีคำขอ preflight
    • QUERY ไม่อยู่ในชุด CORS-safelisted methods

การลงทะเบียนกับ IANA และการเลือกชื่อเมธอด

  • IANA เพิ่มเมธอด QUERY เข้าใน HTTP Method Registry
    • Method Name: QUERY
    • Safe: yes
    • Idempotent: yes
    • Specification: RFC 10008 Section 2
  • IANA เพิ่มฟิลด์ Accept-Query เข้าใน HTTP Field Name Registry
    • Field Name: Accept-Query
    • Status: permanent
    • Structured Type: List
  • ใน HTTP Method Registry มี PROPFIND, REPORT, SEARCH ที่มีคุณสมบัติ safe และ idempotent อยู่ก่อนแล้ว
  • ในช่วงแรกมีการใช้ SEARCH แต่ชื่อเมธอดสุดท้ายคือ QUERY
  • เหตุผลที่เลือก QUERY มีดังนี้
    • ทางเลือกอื่นใช้มีเดียไทป์ทั่วไป application/xml ในเนื้อหาคำขอ และความหมายของคำขอขึ้นอยู่กับเนื้อหาเพียงอย่างเดียว
    • ทางเลือกเหล่านั้นล้วนมีที่มาจากกิจกรรมของ WebDAV
    • QUERY จับความสัมพันธ์กับ query component ของ URI ได้ดี

1 ความคิดเห็น

 
GN⁺ 4 시간 전
ความเห็นจาก Hacker News
  • ถ้ามีตัวอย่างที่สร้างแรงจูงใจได้ชัดเจนกว่านี้ก็น่าจะโน้มน้าวได้มากกว่า แต่นี่กลับใช้ตัวอย่างที่อธิบายด้วย GET ได้ง่ายเกินไป เลยยิ่งทำให้ดูสับสน
    ถึงจะนึกภาพ QUERY ที่ใส่โครงสร้างตัวกรอง JSON ขนาดใหญ่หรืออินพุตรูปภาพไว้ใน request body ก็เถอะ การที่ request body กลายเป็นส่วนหนึ่งของ cache key ก็ยังให้ความรู้สึกแปลกมาก มันทำให้เกิด cache key ที่ผู้ใช้ควบคุมได้แบบไร้ขีดจำกัด และกลยุทธ์การแคชทั่วไปก็แทบไม่มีทางเลือกนอกจากเปรียบเทียบ request body แบบบิตต่อบิตหรือแฮชมัน ซึ่งในสถานการณ์ที่เป็นอันตรายก็ทำให้ cache invalidation ได้ง่ายมาก
    ถ้าจะสร้างบริการที่ต้องใช้การกรองซับซ้อนหรืออินพุตซับซ้อนอย่างรูปภาพ การแคชน่าจะอยู่ไกลจากชั้น HTTP มาก ตัวอย่างเช่น อาจคีย์จากคอลัมน์ข้อมูลรายตัวของ join หรือจาก embedding ที่ใช้ perceptual hash ของอินพุตรูปภาพที่ถอดรหัสแล้ว ซึ่งไม่เกี่ยวกับการแทนค่าบิตบนสายส่งที่ตรงตัวเลย
    ไม่เข้าใจว่าทำไมต้องพยายามจับสิ่งนี้ด้วยวิธีการแบบทั่วไปด้วย สู้แสดงความหมายเชิงการแคชด้วยเฮดเดอร์ใหม่บน POST อย่าง "Vary: request-body" จะดีกว่ามาก เข้ากันได้ย้อนหลังเต็มรูปแบบ และนอกเหนือจากกรณีใช้งาน CDN ราว 0.1% ที่พฤติกรรมนี้อาจมีประโยชน์ ก็ปล่อยให้มองข้ามไปได้

    • ส่วนqueryใน URI ของ GET ในทางปฏิบัติก็แทบไม่มีข้อจำกัดและผู้ใช้ก็ควบคุมได้เหมือนกัน แถมเป็นส่วนหนึ่งของ URI จึงเข้าไปอยู่ใน cache key ด้วย เลยไม่ค่อยเข้าใจว่าทำไมกรณีตรงข้ามนี้ถึงถูกหยิบยกว่าพิเศษนัก
    • ถ้าเบราว์เซอร์อยากได้ cache key ที่เล็กลง ก็เก็บแฮชแบบทนการชนกันของ body ได้ เช่น ใช้ SHA-256
      นึกไม่ออกจริง ๆ ว่าจะมีการโจมตีที่เกี่ยวกับการแคชแบบไหนบ้างที่ใช้กับ query parameter ไม่ได้เหมือนกัน ถ้าอยากทำให้แคชล้น การสร้าง query parameter ยาว 30 ตัวอักษรที่ไม่ซ้ำกันก็ง่ายพอ ๆ กับการสร้าง request body ขนาด 30MB
    • ไม่ใช่ทุกกรณีใช้งานจะอยู่บนอินเทอร์เน็ตสาธารณะ และแค่ไม่ค่อยมีประโยชน์บนอินเทอร์เน็ตสาธารณะ ก็ไม่ได้แปลว่ามาตรฐานไม่ได้
      ในทางปฏิบัติแล้ว ระบบสำหรับอินเทอร์เน็ตสาธารณะก็คงใช้แฮชเข้ารหัสเป็น cache key เพื่อให้มีขนาดคงที่เสมอ อยู่แล้ว cache key ทุกวันนี้ก็รวม URL ที่อาจยาวมากและชุดค่าเฮดเดอร์ที่กำหนดเองได้อยู่แล้ว
    • รูปภาพจะส่งใน request body ก็ได้ แต่ทุกวันนี้ก็ทำผ่าน query parameter แบบ base64 ได้เหมือนกัน ถ้าตั้งใจจะใช้ให้ประหลาด มาตรฐานฉบับร่างไหน ๆ ก็ถูกใช้ในทางไม่ดีได้ทั้งนั้น
      GET ที่มี query parameter อยู่แล้วก็ทึบแสงและทำให้การทำให้แคชใช้ไม่ได้เป็นเรื่องง่าย
    • ยกตัวอย่างเช่น ตอนนี้กำลังทำเซิร์ฟเวอร์ MCPสำหรับฐานข้อมูลอยู่ ใน ChatGPT อยากทำ dry-run POST ที่ rollback ก่อน commit ก่อน แต่ทั้งสองอย่างเป็นเพียงคำขอ POST ที่ต่างกันแค่พร็อพเพอร์ตีเดียว จึงไปกระตุ้นชั้นความปลอดภัยของเครื่องมือบ่อยมาก และด้วยหลายเหตุผล การดีบักหาสาเหตุที่แท้จริงก็ยากด้วย
      แต่ถ้ามี QUERY แล้วตามด้วย POST น่าจะดีกว่า เพราะมันจะกลายเป็นคนละประเภทคำขอ ไม่ใช่แค่คำขอเดียวกันที่ติดธงว่า safe
  • สงสัยว่า HTML form จะเพิ่มการรองรับ QUERYหรือไม่
    QUERY ควรเป็น idempotent ดังนั้นอาจช่วยเลี่ยงคำเตือนให้ส่งซ้ำที่น่ารำคาญเวลารีเฟรชหน้าผลลัพธ์จากการ submit ฟอร์มแบบ POST ได้

    • อยากให้ HTML form รองรับเมธอดมากกว่า GET/POST มาหลายสิบปีแล้ว พอดีมีข้อเสนอของ WHATWG อยู่ ถ้าอยากช่วยส่งเสียงก็ไปที่นี่ได้: https://github.com/whatwg/html/pull/11347
    • ความแปลกอย่างหนึ่งของฟอร์มคือ หน้าผลลัพธ์ของ form POST เป็นหน้าที่มีตำแหน่งที่อยู่ (URL) แต่กลับโหลดผ่านตำแหน่งนั้นไม่ได้ เท่าที่รู้ ความจริงที่ว่าหน้านั้นมาจาก POST ไม่ใช่ GET ไม่ได้ถูกเก็บไว้ตรงไหนที่ผู้ใช้หรือ JS มองเห็นได้ และการรีเฟรชก็ทำงานแบบประหลาด
      ถ้าเพิ่ม method=QUERY เข้าไป ก็จะมีความประหลาดแบบนี้เพิ่มมาอีกสายพันธุ์หนึ่ง
    • เรื่องนี้แก้ด้วยแพตเทิร์น POST-Redirect-GETจะดีกว่า
    • ดู https://github.com/whatwg/html/issues/12594
    • ไม่เคยมีการเพิ่มการรองรับ verb อื่น ๆ เลย แต่ตอนนี้ก็เป็นยุคใหม่แล้ว เลยไม่รู้ว่าจะออกมาอย่างไร
  • สำหรับคนที่ยังอยากทำเหมือนว่ายังอยู่ในศตวรรษก่อน: https://www.rfc-editor.org/rfc/rfc10008.txt

    • น่าจะชอบเอกสารข้อความล้วนที่ยาวและครบถ้วนแบบนี้ไปตลอด มันทำให้นึกถึงช่วงเวลาดี ๆ ตอนเด็กที่อ่าน FAQ เกมวิดีโอ หลายมุมมองแล้วมันเป็นรูปแบบข้อมูลที่เหนือกว่าจริง ๆ
    • รูปแบบการจัดวางสวยมาก ควรเอาไปลอกเป็นเทมเพลตสไตล์สำหรับบันทึกงานภายในองค์กรบ้าง ดูไม่ตกยุคเลย
  • “แนวทางการแนบ body ไปกับคำขอ GET ได้รับการพิจารณาอย่างลึกซึ้งในคณะทำงาน IETF แต่สุดท้ายก็ตัดสินใจสร้างเมธอด QUERY ใหม่แทน การตัดสินใจสร้างเมธอดแยกเกิดจากปัญหาด้านการทำงานร่วมกันในอดีตและการยึดตามคำจำกัดความสถาปัตยกรรมหลักของ HTTP อย่างเคร่งครัด”
    แต่ผมก็ส่งrequest body กับเมธอด GETมาหลายปีแล้วนะ

    • บางload balancerจะทิ้ง body ไป
    • โดยทั่วไปไม่ใช่ความคิดที่ดีนัก ใน HTTP implementation บางตัวทำไม่ได้เลย เช่น fetch
      https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/U...
      “GET request cannot have a body.”
      อาจเกิดปัญหาแปลก ๆ จาก transparent caching ได้ด้วย
  • น่าทึ่งที่ตอนนี้มาถึงเลข RFC 5 หลักแล้ว

  • มีคนลงเดิมพันแบบกำกวมว่า RFC 10000 จะออกเมื่อไร แต่เลขกลับกระโดดจาก 9998 ไป 10008 ตรง ๆ ไม่มีใครชนะเลย
    https://manifold.markets/CollectedOverSpread/when-will-rfc-1...

  • ถ้าจะ query ผลการค้นหาในการ query HTTP ก็ต้องใช้เมธอด QUERY และอย่าใส่ query parameter เพิ่มอีกประมาณนั้น
    ชื่อนี้ชวนสับสน เพราะคำว่า query ก็ถูกใช้เรียก HTTP request โดยทั่วไปอยู่แล้ว
    แค่ดูชื่อ RFC ก็สับสนแล้ว

    • คำว่า query ถูกใช้เรียก HTTP request โดยทั่วไปในวงการไหนกัน? ในภาษาพูดอาจเรียก GET request ว่า query บ้าง แต่กับ POST, PUT, DELETE ไม่เคยเรียกแบบนั้นเลย
    • จริง และมันก็ไม่จำเป็นต้องเป็น query ด้วยซ้ำ อาจเป็นผลลัพธ์แบบ idempotentก็ได้ ถ้าจะให้ดีน่าจะเรียกว่า IPOST หรือ POST แบบ idempotent มากกว่า
      แก้ไข: อ้อ ประกาศให้ QUERY เป็นเมธอด “safe” ที่ไม่มีผลข้างเคียงเพื่อให้แคชได้สินะ เข้าใจผิดไป
  • ถ้านี่กลายเป็นสิ่งที่มาแทน GET ที่มี query string ในโลกจริงได้จริง ก็หวังจริง ๆ ว่าที่คั่นหน้าในเบราว์เซอร์จะรองรับการเก็บพารามิเตอร์ของคำขอไว้ด้วย

    • คิดว่าคงไม่ถึงขั้นนั้น น่าจะมาแทนที่จุดที่ตอนนี้ใช้ POST เพื่อการ query มากกว่า
  • รู้ว่าอยู่นอกขอบเขตของ RFC นี้ แต่ชอบที่ถ้าขยายต่อได้ง่าย มันอาจทำให้ JS EventSource ใช้กับการ query AI แบบสตรีมมิงได้ด้วย
    เพราะคำขอต้องมี body ทุกคนเลยใช้ POST และผลลัพธ์แบบสตรีมก็มักใช้โปรโตคอล text/event-stream ใน response แต่จริง ๆ แล้วไม่มีการเปลี่ยนสถานะ จึงไม่ค่อยตรงเชิงเทคนิค และ EventSource ก็ยืนกรานว่าจะใช้ได้แค่ GET เท่านั้น เลยทำให้ API จำนวนมากต้องไปเขียนความสามารถเดียวกันใหม่ด้วย parser ของตัวเอง

  • พอเห็น GET: Content (body) "no defined semantics" ก็คิดว่าน่าจะไม่เป็นไรถ้าจะอนุญาตให้เมธอด GET มี body แต่ตามสเปกเดิมแล้วbody ของ GET ควรถูกเพิกเฉยโดยสิ้นเชิง
    อีกอย่าง ถ้าส่วนสำคัญของคำขอไปอยู่ใน body ที่ถูกตัดออก การแคชก็อาจพังได้

    • GET ที่มีแค่ URI มีความหมายเชิง semantics ว่าเป็นการดึง representation ปัจจุบันของ resource นั่นคือรูปแบบพื้นฐานที่สุดของไฮเปอร์ลิงก์ และค่อนข้างสำคัญต่อวิธีที่เว็บทำงาน
      ถ้าเพิ่มพารามิเตอร์ใน body ให้ GET ก็จะทำให้ไม่สามารถถือว่าคำขอสองอันที่ใช้ URI เดียวกันชี้ไปยังสิ่งเดียวกันได้อีก ซึ่งเป็นการทำลายข้อจำกัดของเมธอดนี้