Protokol Tamponları 3'te neden gerekli ve isteğe bağlı kaldırılır?


214

Geçenlerde kullanıyorum gRPCile proto3, ben fark ettik requiredve optionalyeni sözdiziminde kaldırılmıştır.

Herkes proto3 neden gerekli / isteğe bağlı kaldırıldı açıklayabilir misiniz? Bu tür kısıtlamalar, tanımı sağlam kılmak için gerekli görünmektedir.

sözdizimi proto2:

message SearchRequest {
  required string query = 1;
  optional int32 page_number = 2;
  optional int32 result_per_page = 3;
}

sözdizimi proto3:

syntax = "proto3";
message SearchRequest {
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
}

Yanıtlar:


390

Yararlılığı requiredbirçok tartışma ve alev savaşının kalbinde olmuştur. Her iki tarafta da büyük kamplar vardı. Bir kamp, ​​bir değerin mevcut olduğunu garanti etmeyi severdi ve sınırlamaları ile yaşamak isterdi, ancak diğer kamp required, güvenli bir şekilde eklenemeyeceği veya kaldırılamayacağı için tehlikeli veya yararsız hissetti .

requiredAlanların neden az kullanılmaları gerektiğinin gerekçelerini daha fazla açıklayayım . Zaten bir protokol kullanıyorsanız, zorunlu bir alan ekleyemezsiniz çünkü eski uygulamaların bu alanı sağlamaması ve genel olarak uygulamalar hatayı iyi işlemez. Önce tüm eski uygulamaların yükseltildiğinden emin olabilirsiniz, ancak bir hata yapmak kolay olabilir ve protoları herhangi bir veri deposunda (kısa süreli, hatta memcached gibi) saklıyorsanız yardımcı olmaz . Gerekli alan kaldırılırken aynı durum geçerlidir.

Zorunlu alanların birçoğu zorunlu olana kadar "açıkça" zorunluydu. Diyelim ki idbir Getyöntem için bir alanınız var . Bu kesinlikle gerekli. Dışında, daha sonra idint'den dizeye veya int32'den int64'e değiştirmeniz gerekebilir . Bu, yeni bir muchBetterIdalan eklemeyi gerektirir ve şimdi belirtilmesi gereken eski idalanla bırakılırsınız , ancak sonunda tamamen göz ardı edilir.

Bu iki sorun birleştirildiğinde, yararlı requiredalanların sayısı sınırlı hale gelir ve kamplar hala değerinin olup olmadığını tartışırlar. Muhalifler requiredbu fikre mutlaka karşı değil, şu anki biçimine karşıydılar. Bazıları , requireddaha gelişmiş bir şeyle birlikte kontrol edebilecek daha iyi bir doğrulama kütüphanesi geliştirmeyi name.length > 10ve aynı zamanda daha iyi bir başarısızlık modeline sahip olmayı önerdi .

Proto3 genel olarak basitliği destekliyor gibi görünüyor ve requiredkaldırma işlemi daha basit. Ancak, daha ikna edici olabilir, requiredilkel öğeler için alan varlığının kaldırılması ve geçersiz kılınan varsayılan değerlerin kaldırılması gibi diğer özelliklerle birleştirildiğinde proto3 için mantıklı bir şekilde kaldırılır.

Ben bir protobuf geliştiricisi değilim ve bu konuda hiçbir şekilde yetkili değilim, ama yine de açıklamanın yararlı olduğunu umuyorum.


23
Evet. Ayrıca, zorunlu alanlarla korkunç bir şekilde yanlış gidebilecek şeylerin bu geniş açıklamasına da bakın: capnproto.org/…
Kenton Varda

8
İsteğe bağlı kaldırılmaz; proto3'te her şey isteğe bağlıdır. Ancak evet, ilkel öğeler için alan görünürlüğü (has_field) kaldırıldı . Alan görünürlüğüne ihtiyacınız varsa , iletileri olan wrappers.proto kullanın StringValue. İleti oldukları için has_field kullanılabilir. Bu birçok dilde yaygın olarak kullanılan "boks" dur.
Eric Anderson

9
Aksine, proto3'te "isteğe bağlı" kaldırılmış gibi görünüyor. Her alan vardır ve varsayılan bir değerle doldurulur. İlkel alanın kullanıcı tarafından mı yoksa varsayılan olarak mı doldurulduğunu bilmenin bir yolu yoktur. Temel olarak işaretçiler olan ileti alanları boş değerlere sahip olmaları nedeniyle isteğe bağlıdır.
Vagrant

14
Protobuf'un alev savaşlarına başlamak için özel olarak tasarlanmış bir dil olduğunu hissediyorum
Randy L

5
Çoğu kişi API'larını sürümlemek istemiyor gibi görünüyor. "Geriye dönük uyumluluk" için her şeyi isteğe bağlı hale getirmeleri daha kolaydır.
Holoceo

41

Açıklamayı bu protobuf Github sayısında bulabilirsiniz :

Gerekli alanları genellikle zararlı olarak kabul ettikleri ve protobufun uyumluluk semantiklerini ihlal ettiği için proto3'e gerekli alanları bıraktık. Protobuf kullanma fikri, yeni / eski ikili dosyalarla tam ileri / geri uyumluyken protokol tanımınıza alan eklemenize / kaldırmanıza izin vermesidir. Zorunlu alanlar bunu kırıyor. .Proto tanımına asla gerekli bir alanı güvenli bir şekilde ekleyemezsiniz veya bu gerekli alanların her ikisini de tel uyumluluğunu bozduğundan güvenli bir şekilde kaldıramazsınız. Örneğin, bir .proto tanımına zorunlu bir alan eklerseniz, yeni tanımla oluşturulan ikili dosyalar, eski alan kullanılarak gerekli alan bulunmadığından, eski tanım kullanılarak serileştirilmiş verileri ayrıştıramaz. Burada karmaşık bir sistem. proto tanımları sistemin birçok farklı bileşeni arasında yaygın olarak paylaşılır, gerekli alanları eklemek / kaldırmak sistemin birden çok parçasını kolayca düşürebilir. Bunun birçok kez neden olduğu üretim sorunlarını gördük ve Google'da herkesin zorunlu alanları eklemesi / kaldırması hemen hemen her yerde yasaklandı. Bu nedenle proto3'teki zorunlu alanları tamamen kaldırdık.

"Gerekli" öğesinin kaldırılmasından sonra "isteğe bağlı" yalnızca gereksizdir, bu nedenle "isteğe bağlı" ifadesini de kaldırdık.


6
Anlamıyorum; Seriden kaldırma işleminden sonra ileti bırakmak ile serileştirme arasındaki fark nedir? gerekli bir alan (ör. id) içermediğinden eski istemci tarafından bırakılır.
Shmuel H.

6
@ShmuelH ile hemfikir olmaya meyilliyim. zorunlu alanlar şu ya da bu şekilde bir API'nin parçası olacaktır. Her iki tarafa da sözdizimi ile otomatik olarak destekleniyor veya arka uçta gizleniyor, hala orada. Api tanımında da görünür hale getirebilir
Cruncher

7
@ShmuelH'ye tamamen katılıyorum. alanlar bir şekilde bir API'de zorunludur ve müşterinin bunu bilmesi için yararlıdır. Bu bana henüz tam sürümleme yapmadığımızı düşündürüyor.
patrickbarker

6
@ShmuelH için başka bir oy. Eğer bir geriye-uyumsuz bir şekilde (gerekli bir alan ekleyerek) da API değiştirirseniz, o zaman mutlaka istediğiniz sizin ayrıştırıcı olduğunu tespit etmek? API'lerinizi sürümlendirin! İsterseniz, Protobuf'ta tamamen yapabilirsiniz oneof { MessageV1, MessageV2, etc. }.
Timmmm

1
Başlangıçta gerekli alanlara sahip olmayı haklı çıkaramadı. Gerekli bir alan eklemek uyumsuz bir değişikliktir ve genellikle protokol sürümü değişikliği (yani yeni bir mesaj türü) ile ele alınmalıdır.
kan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.