Por que Protobuf 3 tornou todos os campos nas mensagens opcionais?

6

A sintaxe 3 do protobuf tornou todos os campos opcionais eliminando as palavras-chave required e optional da sintaxe anterior do proto2. Lendo alguns comentários de desenvolvedores , parece que foi feito para melhorar a compatibilidade binária para frente / para trás.

Mas, para mim, isso pode ser reforçado apenas com o controle de versão dos nomes dos pacotes, digamos com.example.messages.v1 , e depois permitir que os clientes implementem os desserializadores que eles entendem. Ao mesmo tempo, remove alguns contratos declarados como um tipo que são úteis do ponto de vista da engenharia de software. Por exemplo, se eu tiver

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

No proto3 é possível criar um Location com metade do backup mas perfeitamente válido, não fornecendo um dos campos obrigatórios.

Isso não é uma grande desvantagem ao criar um formato de serialização baseado em esquema para trocar dados entre clientes? Não é pior mover código de validação extra para cada cliente, verificando se todos os campos obrigatórios têm valores válidos?

    
por tonicebrian 08.06.2017 / 11:06
fonte

1 resposta

6

O proto3 faz um número de alterações direcionadas (pelo que entendi) para torná-lo muito mais utilizável em cenários de plataforma cruzada. O rastreamento explícito de "atribuído" vs "não atribuído, mas informando o valor padrão" pode ser muito difícil de implementar em algumas das plataformas de destino e também pode ser confuso de usar. Como tal, o proto3 adota uma abordagem muito mais simples:

  • o valor padrão implícito é o valor zero natural (números / enums), false (booleans) ou a string vazia (strings)
  • somente o padrão implícito é permitido; nenhum outro valor padrão é permitido
  • se um campo tiver esse valor padrão, ele não será serializado; não importa se foi atribuído explicitamente a zero / false / empty-string vs nunca atribuído
  • por causa disso, não há conceito de "obrigatório", já que "atribuído explicitamente um valor zero" e "nunca atribuído um valor" parecem idênticos

In proto3 it is possible to create a half backed but perfectly valid Location by not providing one of the required fields.

O outro valor é: zero. O fato de você não explicitamente atribuí-lo a zero é irrelevante. Se isso é desejável ou não, depende de você, mas faz sentido para mim e é como "inicializar um novo objeto / estrutura" funciona em uma ampla gama de plataformas.

Isn't worse to move extra validation code to each client checking that all required fields have valid values?

Não há nada para validar! O layout é exatamente o que seria se o valor zero fosse explicitamente atribuído. Se isso é legal, é legal. Se é ilegal (porque zero não faz sentido para você), é ilegal; mas seria ilegal se era explícito ou implícito. A quantidade de validação envolvida não muda.

Isn't that a big drawback when creating a schema based serialization format for exchanging data between clients?

Normalmente não, não ... especialmente porque a versão do esquema é explícita. Se você quiser usar proto2: use proto2. Nada muda automaticamente.

    
por 08.06.2017 / 14:48
fonte