Mengapa Protobuf 3 menjadikan semua bidang pada pesan opsional?

15

Sintaks 3 protobuf membuat semua bidang opsional menjatuhkan kata kunci requireddan optionaldari sintaks proto2 sebelumnya. Membaca beberapa komentar dari pengembang tampaknya itu dilakukan untuk meningkatkan kompatibilitas biner maju / mundur.

Tetapi bagi saya, itu bisa ditegakkan dengan hanya versi nama paket, katakan com.example.messages.v1dan kemudian biarkan klien untuk menerapkan deserializer yang mereka mengerti. Pada saat yang sama menghapus beberapa kontrak yang dinyatakan sebagai jenis yang berguna dari sudut pandang rekayasa perangkat lunak. Misalnya kalau sudah

message Location {
   double latitude = 1;
   double longitude = 2;
}

Dalam proto3 dimungkinkan untuk membuat setengah didukung tetapi valid sempurna Locationdengan tidak memberikan salah satu bidang yang diperlukan.

Bukankah itu kelemahan besar ketika membuat format serialisasi berbasis skema untuk bertukar data antara klien? Bukankah lebih buruk untuk memindahkan kode validasi tambahan ke setiap klien memeriksa bahwa semua bidang yang diperlukan memiliki nilai yang valid?

tonicebrian
sumber
leanpub.com/esversioning
VoiceOfUnreason

Jawaban:

13

proto3 membuat sejumlah perubahan yang ditujukan (seperti yang saya mengerti) untuk membuatnya jauh lebih berguna dalam skenario lintas platform. Pelacakan eksplisit "ditugaskan" vs "tidak ditugaskan tetapi melaporkan nilai default" bisa sangat sulit untuk diterapkan pada beberapa platform target, dan juga bisa membingungkan untuk digunakan. Dengan demikian, proto3 mengadopsi pendekatan yang lebih sederhana:

  • nilai default implisit adalah nilai nol alami (angka / enum), false (boolean) atau string kosong (string)
  • hanya standar implisit yang diizinkan; tidak ada nilai default lain yang diizinkan
  • jika suatu bidang memiliki nilai default itu, itu bukan serial; tidak masalah apakah itu ditugaskan secara eksplisit ke nol / false / string kosong vs tidak pernah ditugaskan
  • karena itu, tidak ada konsep "wajib", karena "secara eksplisit menetapkan nilai nol" dan "tidak pernah menetapkan nilai" terlihat identik

Dalam proto3 dimungkinkan untuk membuat Lokasi yang setengah didukung tetapi valid dengan tidak menyediakan salah satu bidang yang diperlukan.

Nilai lainnya adalah: nol. Fakta bahwa Anda tidak secara eksplisit menetapkannya ke nol adalah moot. Apakah ini diinginkan atau tidak tergantung pada Anda, tetapi masuk akal bagi saya dan bagaimana banyak "menginisialisasi objek / struct baru" bekerja pada berbagai platform.

Bukankah lebih buruk untuk memindahkan kode validasi tambahan ke setiap klien memeriksa bahwa semua bidang yang diperlukan memiliki nilai yang valid?

Tidak ada yang bisa divalidasi! Tata letak persis seperti apa jadinya jika nilai nol ditetapkan secara eksplisit. Jika itu legal, itu legal. Jika itu ilegal (karena nol tidak masuk akal bagi Anda), itu ilegal; tetapi akan ilegal apakah itu eksplisit atau implisit. Jumlah validasi yang terlibat tidak berubah.

Bukankah itu kelemahan besar ketika membuat format serialisasi berbasis skema untuk bertukar data antara klien?

Tidak biasanya, tidak ... terutama karena versi skema eksplisit. Jika Anda ingin menggunakan proto2: gunakan proto2. Tidak ada yang berubah secara otomatis.

Marc Gravell
sumber
Saya ingin tahu apa yang "hanya nol alami sebagai bawaan" yang membeli mereka, karena protobuf tidak dapat digunakan tanpa skema. Memastikan default konsisten tidak terdengar jauh lebih sulit daripada memastikan skema konsisten di tempat pertama.
CodesInChaos
1
@CodesInChaos itu menarik, karena saya sudah melakukan skema-kurang protobuf untuk ... yah, selamanya :) di protobuf-net, diharapkan sebagian besar pengguna akan menjadi kode-pertama dan skema-kurang. Dan yang menarik (bagi saya, setidaknya) sebagian besar strategi default "tetap sederhana, bodoh" yang menggunakan protobuf-net persis sama dengan apa yang dipilih untuk digunakan proto3. Saya tidak akan mengklaim bahwa ini memvalidasi keputusan partisan acak saya, tapi ... itu benar-benar :)
Marc Gravell
Saya menganggap kelas C # semacam skema dan Anda tentu dapat menentukan nilai default melalui atribut. Bandingkan dengan misalnya msgpack atau json, yang dapat membuat struktur data yang berarti tanpa skema apa pun.
CodesInChaos
@CodesInChaos setuju dan mencatat - dan ya, protobuf-net akan mengamati dan menghormati setiap deklarasi seperti itu
Marc Gravell