
Go Serialization 02: ทดลอง MessagePack จาก struct เดิม
MessagePack เป็นจุดเริ่มที่ปรับโค้ดไม่มากครับ เราใช้ struct เดิมเพิ่ม tags แล้วให้ library แปลงเป็น binary แต่ยังต้องตรวจว่าทั้งสองฝั่งได้ความหมายของข้อมูลตรงกัน
เตรียมโปรเจกต์
ดาวน์โหลด โปรเจกต์ 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. ดู adapter ที่เปลี่ยน
เปิด codecs.go ตรง codec ชื่อ msgpack ตัวอย่างบางส่วนของ encode/decode คือ:
wire, err := msgpack.Marshal(catalog)
if err != nil { return err }
var decoded Catalog
err = msgpack.Unmarshal(wire, &decoded)
โปรเจกต์เต็มใช้ Decoder พร้อมตรวจ trailing bytes และ validate หลัง decode อีกครั้ง เพื่อไม่ให้รับ payload ต่อท้ายโดยไม่รู้ตัว เราใช้ map encoding ที่มีชื่อฟิลด์ ไม่ได้เปิด array encoding เพื่อทำให้ตัวเลขดูเล็กลงโดยเปลี่ยนสัญญาเงียบ ๆ
2. รันและตรวจ
go test -run 'TestRoundTrip/msgpack|TestInvalidInputs/msgpack' -v
go test -run '^$' -bench 'BenchmarkCodecs/msgpack' -benchmem -benchtime=300ms -count=5
go run ./cmd/sizes
ผลที่ตรวจได้: ชื่อไทย ราคา และ tags กลับมาตรงกับ JSON baseline ข้อมูลเสียที่ tests ระบุคืน error ส่วน sizes มีแถว msgpack สำหรับ 1, 100, 1000 รายการ ขนาดที่ลดไม่ได้รับประกันว่า encode จะเร็วขึ้น เพราะขึ้นกับ implementation และรูปแบบ struct ด้วย
3. เปรียบเทียบอย่างยุติธรรม
เทียบ msgpack/100/decode กับ json/100/decode และแยก gzip จาก raw bytes การบีบข้อความ JSON ที่มีชื่อฟิลด์ซ้ำมากอาจลดช่องว่างด้านขนาดได้มากกว่าที่มองจากข้อมูลดิบ
แบบฝึกหัด
เพิ่มฟิลด์ Currency ให้ struct และ fixture แล้วตรวจ round-trip ใหม่ ลองเอา tag ของ MessagePack ออกหนึ่งฟิลด์ สังเกตชื่อ key ที่เปลี่ยนและคิดว่าผู้ใช้ภาษาคนละภาษาจะอ่านอย่างไร ก่อนใช้จริงให้ตกลงชนิดข้อมูลและชื่อฟิลด์เหมือนการออกแบบ API ทั่วไป