Чому Protobuf 3 зробив усі поля повідомлень необов’язковими?


15

Синтаксис 3 протобуфа зробив усі поля необов’язковими для випадання ключових слів requiredта optionalпопереднього синтаксису прото2. Читаючи деякі коментарі розробників, здається, що це було зроблено для підвищення бінарної сумісності вперед / назад.

Але для мене це може бути застосовано просто версією імен пакунків, скажіть, com.example.messages.v1а потім дозвольте клієнтам впроваджувати розбираються у них десеріалізатори. Одночасно він вилучає деякі контракти, зазначені як тип, корисні з точки зору інженерії програмного забезпечення. Наприклад, якщо я маю

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

У proto3 можна створити напівзахисну, але цілком дійсну Location, не надавши жодне з необхідних полів.

Це не великий недолік під час створення формату серіалізації на основі схеми для обміну даними між клієнтами? Чи не гірше перемістити додатковий код перевірки на кожного клієнта, перевіривши, чи всі обов'язкові поля мають дійсні значення?


Відповіді:


13

proto3 вносить ряд змін, спрямованих (наскільки я розумію), щоб зробити його набагато більш корисним у кросплатформних сценаріях. Явне відстеження "призначеного" проти "не призначене, але повідомлення про значення за замовчуванням" може бути дуже важким для реалізації на деяких цільових платформах, а також може заплутати використання. Таким чином, proto3 використовує набагато простіший підхід:

  • неявне значення за замовчуванням є природним нульове значення (число / перерахувань), помилкові (булеві) або порожній рядок (рядки)
  • дозволений лише неявний дефолт; ніякі інші значення за замовчуванням не дозволяються
  • якщо поле має це значення за замовчуванням, воно не серіалізується; не має значення, було призначено явно нулю / false / empty-string vs ніколи не призначено
  • через це не існує поняття "потрібно", оскільки "явно присвоєно нульове значення" і "ніколи не присвоєне значення" виглядають ідентичними

У proto3 можна створити напівзахисне, але цілком дійсне місце розташування, не надавши жодного з необхідних полів.

Інше значення: нуль. Справа в тому, що ви явно не призначили його нулю. Бажано чи ні, це залежить від вас, але для мене це має сенс і те, як багато "ініціалізувати новий об'єкт / структуру" працює на широкому діапазоні платформ.

Чи не гірше перемістити додатковий код перевірки на кожного клієнта, перевіривши, чи всі обов'язкові поля мають дійсні значення?

Немає чого підтверджувати! Макет саме такий, який був би, якби явно було присвоєне значення нуля. Якщо це законно, то це законно. Якщо це незаконно (оскільки нуль для вас не має сенсу), це незаконно; але це було б незаконно, будь то явне чи неявне. Обсяг валідації не змінюється.

Це не великий недолік під час створення формату серіалізації на основі схеми для обміну даними між клієнтами?

Зазвичай, ні ... тим більше, що версія схеми явна. Якщо ви хочете використовувати proto2: використовуйте proto2. Нічого не змінюється автоматично.


Мені цікаво, що "лише природний нуль за замовчуванням" купує їх, оскільки протобуф насправді не підходить без якоїсь схеми. Забезпечення послідовних значень за замовчуванням не звучить набагато складніше, ніж в першу чергу забезпечення послідовних схем.
CodesInChaos

1
@CodesInChaos, що цікаво, адже я робив протобуф без схем для ... ну, назавжди :) у protobuf-net, очікується, що більшість користувачів будуть першими з кодом та без схем. І що цікаво (щонайменше, для мене) більшість стратегій "тримати це просто, дурні" за замовчуванням, якими користується протобуф-мережа, точно така ж, як і прото3, обраний для використання. Я не збираюся стверджувати, що це підтверджує мої випадкові партизанські рішення, але ... це абсолютно так :)
Марк Гравелл

Я вважаю клас C # своєрідною схемою, і ви, звичайно, можете вказати значення за замовчуванням за допомогою атрибутів. Порівняйте це, наприклад, з msgpack або json, які можуть створити змістовну структуру даних без будь-якої схеми.
CodesInChaos

@CodesInChaos погодився і зазначив - і так, протобуф-мережа буде дотримуватися і поважати будь-які такі декларації
Марк Гравелл
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.