การวิพากษ์วิจารณ์อย่างละเอียดต่อ Protocol Buffers ของ Google ได้จุดประกายการถกเถียงอย่างเข้มข้นในชุมชนนักพัฒนา โดยเน้นไปที่ปัญหาการออกแบบพื้นฐานที่ยังคงสร้างความหงุดหงิดให้กับวิศวกรที่ทำงานกับรูปแบบการ serialization นี้ การอภิปรายมุ่งเน้นไปที่ข้อจำกัดของระบบประเภทข้อมูล ความท้าทายในการรองรับความเข้ากันได้แบบย้อนหลัง และช่องว่างระหว่างรูปแบบ wire format ของ protobuf กับความต้องการในการใช้งานจริง
ข้อจำกัดของระบบประเภทข้อมูลสร้างความเสียดทานในการพัฒนา
ข้อร้องเรียนที่สำคัญที่สุดมุ่งเน้นไปที่ข้อจำกัดโดยพลการมากมายของ protobuf ที่ป้องกันไม่ให้ฟีเจอร์ต่างๆ ทำงานร่วมกันได้อย่างราบรื่น นักพัฒนาพบข้อจำกัดเป็นประจำ เช่น ไม่สามารถใช้ enum เป็น key ของ map ข้อจำกัดใน nested maps และความจริงที่ว่าฟิลด์ oneof ไม่สามารถทำซ้ำได้ ข้อจำกัดเหล่านี้บังคับให้วิศวกรต้องเขียน workaround และฟังก์ชันการแยกวิเคราะห์แบบกำหนดเอง ซึ่งทำลายจุดประสงค์ของโค้ดที่สร้างขึ้นอัตโนมัติ
ปัญหาที่น่าหงุดหงิดอย่างหนึ่งเกี่ยวข้องกับข้อจำกัดของ key ใน map หลายโปรเจ็กต์ต้องใช้ string-based maps ทั่วทั้ง codebase หรือแปลงด้วยตนเองระหว่าง string maps และโครงสร้างที่มีประเภทข้อมูลที่เหมาะสมหลังจาก deserialization สิ่งนี้สร้างภาระการบำรุงรักษาเพิ่มเติมและแหล่งที่มาของข้อผิดพลาดที่อาจเกิดขึ้นในระบบการผลิต
ข้อจำกัดสำคัญของ Protocol Buffers
- ข้อจำกัดของ Map: ไม่สามารถใช้ enums เป็น keys ได้, ไม่มี nested maps, keys จำกัดเฉพาะ strings/integers
- Type Composition: ฟิลด์
oneof
ไม่สามารถเป็นrepeated
ได้, การสนับสนุน parameterization มีข้อจำกัด - คุณภาพการสนับสนุนภาษา: Go (ดี) เทียบกับ Python/Ruby/TypeScript (มีปัญหา)
- การจัดการฟิลด์: ฟิลด์ทั้งหมดเป็น optional โดยค่าเริ่มต้น, การเริ่มต้นด้วย zero-value อาจปิดบังข้อผิดพลาด
รูปแบบ Serialization ทางเลือก
- Simple Binary Encoding ( SBE ): จัดการ backwards/forwards compatibility ได้ดีกว่า
- Typical: แนะนำ "asymmetric fields" เพื่อการพัฒนา schema ที่ปลอดภัยกว่า
- แนวทางแบบดั้งเดิม: REST/JSON สำหรับกรณีการใช้งานที่เรียบง่ายโดยไม่ต้องการประสิทธิภาพสูงสุด
คุณภาพของโค้ดที่สร้างขึ้นแตกต่างกันอย่างมากตามภาษา
ประสบการณ์ของนักพัฒนากับ Protocol Buffers ขึ้นอยู่กับภาษาโปรแกรมเป้าหมายเป็นอย่างมาก ในขณะที่นักพัฒนา Go โดยทั่วไปรายงานประสบการณ์เชิงบวก ผู้ที่ทำงานกับการใช้งาน Python หรือ Ruby เผชิญกับความท้าทายอย่างมาก การสร้างโค้ด TypeScript ได้รับการวิพากษ์วิจารณ์เป็นพิเศษสำหรับการทำเครื่องหมายฟิลด์เกือบทั้งหมดเป็น optional บังคับให้ทีมต้องเขียนชั้นการตรวจสอบเพิ่มเติม
เราต้องเขียนโค้ดของเราเองเพื่อแยกวิเคราะห์การตอบสนองจากการตอบสนองของ TypeScript client ที่สร้างขึ้นอย่างมีประโยชน์ นี่หมายความว่าเราต้องจัดการกับการปฏิเสธการตอบสนองที่ไร้สาระซึ่งฟิลด์ที่จำเป็นจริงๆ ไม่มีอยู่
คุณภาพที่ขึ้นอยู่กับภาษานี้สร้างประสบการณ์ที่ไม่สอดคล้องกันในทีมพัฒนาและสามารถมีอิทธิพลต่อตัวเลือกเทคโนโลยีนอกเหนือจากความต้องการ serialization เท่านั้น
ประโยชน์ของความเข้ากันได้แบบย้อนหลังถูกตั้งคำถาม
แม้ว่า Protocol Buffers จะโฆษณาความเข้ากันได้แบบย้อนหลังและไปข้างหน้าเป็นฟีเจอร์หลัก นักพัฒนารายงานผลลัพธ์ที่หลากหลายในทางปฏิบัติ แนวทางของรูปแบบในการจัดการฟิลด์ที่หายไปผ่านการเริ่มต้น zero-value สามารถปกปิดปัญหาข้อมูลจริงและสร้างบั๊กที่ละเอียดอ่อน วิศวกรบางคนโต้แย้งว่าประโยชน์ด้านความเข้ากันได้ไม่สมเหตุสมผลกับความซับซ้อนที่เพิ่มขึ้นสำหรับกรณีการใช้งานหลายๆ แบบ
ชุมชนได้ระบุรูปแบบ serialization ทางเลือกที่ให้การรับประกันความเข้ากันได้ที่คล้ายกันด้วยระบบประเภทข้อมูลที่สะอาดกว่า อย่างไรก็ตาม การนำ protobuf ไปใช้อย่างแพร่หลายและระบบนิเวศของเครื่องมือทำให้การย้ายข้อมูลเป็นเรื่องท้าทายสำหรับโปรเจ็กต์ที่มีอยู่แล้ว
โซลูชันทางเลือกเกิดขึ้น
นักพัฒนาหลายคนได้ชี้ไปที่รูปแบบ serialization ใหม่ๆ ที่แก้ไขข้อจำกัดของ protobuf ในขณะที่รักษาฟีเจอร์ความเข้ากันได้ไว้ Simple Binary Encoding ( SBE ) และ Typical ได้รับความสนใจสำหรับแนวทางที่มีหลักการมากกว่าต่อการพัฒนา schema และความปลอดภัยของประเภทข้อมูล ทางเลือกเหล่านี้แสดงให้เห็นว่าปัญหาไม่ได้เป็นสิ่งที่มีอยู่ในรูปแบบ serialization แต่เป็นตัวเลือกการออกแบบเฉพาะ
การถกเถียงที่กำลังดำเนินอยู่สะท้อนความตึงเครียดที่กว้างขึ้นในวิศวกรรมซอฟต์แวร์ระหว่างโซลูชันที่ใช้งานได้จริงที่ทำงานในระดับใหญ่และการออกแบบที่มีเหตุผลทางทฤษฎีที่ให้ประสบการณ์นักพัฒนาที่ดีกว่า ในขณะที่ Protocol Buffers ยังคงให้บริการองค์กรหลายแห่งอย่างมีประสิทธิภาพ การวิพากษ์วิจารณ์เน้นพื้นที่ที่รูปแบบสามารถพัฒนาเพื่อให้บริการแนวทางการพัฒนาสมัยใหม่ได้ดีขึ้น
อ้างอิง: Protobuffers Are Wrong