
Go Serialization 05: FlatBuffers อ่านตรงหรือ decode ทั้งชุด
FlatBuffers เปิดทางให้อ่านบางฟิลด์จาก buffer โดยตรง จุดนี้มีประโยชน์เมื่อแอปไม่ได้ต้องการ object ทั้งชุดครับ แต่ถ้าจะเทียบกับ JSON decode ทั้งก้อน เราต้องสร้าง Catalog กลับมาให้ครบเช่นกัน
เตรียมโปรเจกต์
ดาวน์โหลด โปรเจกต์ Go พร้อม schemas, generated code, tests และผลดิบ แล้วแตกไฟล์ ใช้ Go 1.27 ขึ้นไป เปิด terminal ในโฟลเดอร์ go-api-serialization และรัน go mod download ครั้งแรก ไม่ต้องติดตั้ง compiler ของ schema เพื่อเริ่มเรียน
โค้ดบนหน้านี้เป็นตัวอย่างบางส่วน (fragment) เพื่ออธิบายจุดสำคัญ คำสั่ง shell ตรวจ syntax ส่วน โปรเจกต์เต็มตรวจด้วย go test ./... ใน quality gate ไม่ควรนำ fragment ไปรันเป็นโปรแกรมเดี่ยว
1. ดู schema และ generated accessors
เปิด schemas/catalog.fbs และ internal/fb/ แล้วดู flatbuffers.go ตัว builder สร้าง strings, vectors และ tables ก่อนปิด buffer ด้วย identifier SCAT ส่วน decode ตรวจ identifier และขนาดก่อนใช้ offsets
ตัวอย่างบางส่วนของการอ่านฟิลด์เดียว:
catalog := fb.GetRootAsCatalog(data, 0)
var product fb.Product
if catalog.Products(&product, 0) {
price := product.PriceCents()
_ = price
}
fragment นี้ยังไม่มี validation ให้ใช้ FirstPriceFlat ในโปรเจกต์เต็มซึ่งตรวจความยาว จำนวนและ index พร้อมแปลง panic จากข้อมูลเสียเป็น error ถึงอย่างนั้นก็ไม่ใช่ complete buffer verifier สำหรับข้อมูลจากผู้โจมตี ต้องมีขอบเขตความเชื่อถือที่เหมาะสมก่อนใช้จริง
2. แยกการวัดสองชนิด
go test -run 'TestRoundTrip/flatbuffers|TestInvalidInputs/flatbuffers|TestFlatBuffersDirectRead' -v
go test -run '^$' -bench 'BenchmarkCodecs/flatbuffers' -benchmem -benchtime=300ms -count=5
go test -run '^$' -bench '^BenchmarkFlatBuffersFirstPrice$' -benchmem -benchtime=300ms -count=5
ผลที่ตรวจได้: full decode คืนทุก field และ tags ของทุกสินค้า ส่วน direct read คืนราคา 12500 ของสินค้าชิ้นแรก การเข้าถึงฟิลด์เดียวกับ decode ตอบคนละคำถาม ห้ามนำตัวเลขทั้งสองมาตั้งเป็นกราฟแข่งกัน
เมื่อ materialize เป็น Go structs เราสร้าง strings/slices และ copy ข้อมูลกลับมา จึงยังมี allocations แม้ format จะรองรับ direct access และถ้าเก็บ reference ไปยัง buffer ต้องไม่แก้หรือคืน buffer ให้ pool ก่อนอ่านเสร็จ
3. Regenerate เมื่อแก้ schema
ติดตั้ง flatc 25.12.19 จาก official releases แล้วรัน:
flatc --go -o internal schemas/catalog.fbs
go test ./...
แบบฝึกหัด
เพิ่มฟังก์ชันรวมราคาสินค้าทั้งหมดโดยอ่านจาก buffer แล้วเขียนอีกฟังก์ชันที่รวมราคาหลัง full decode ให้ทั้งคู่คืนผลเท่ากันก่อน benchmark ระบุให้ชัดว่างานหนึ่งคืนเพียงผลรวม อีกงานคืน Catalog ด้วย ถ้าต้องการแข่งอย่างยุติธรรม ให้เทียบ end-to-end task ที่ใช้ผลรวมเหมือนกัน