Protobuf
Como funciona?
- Cria-se um arquivo .proto com a definição da estrutura de dados a ser utilizada.
- Compila-se este arquivo para gerar uma classe que representa essa estrutura na sua aplicação, no caso, em C#.
- Instancia-se a classe na aplicação e atribuí-se os dados
- Realiza-se a encodificação para o formato _binário_, utilizando métodos presentes na classe C# gerada.
- O array de bytes é então trafegado 🙂
syntax = "proto3";
message Person {
string Name = 1;
int32 Id = 2;
string Email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
string Number = 1;
PhoneType Type = 2;
}
PhoneNumber Phone = 4;
}
- tipos de dados
- nome das propriedades
- posição destes dados no momento de realizar a encodificação/decodificação
- etc.
Onde baixar o compilador?
dotnet global tool – protoc
dotnet tool install --global protoc --version 3.6.1
Chocolatey – protoc
choco install protoc --version 3.6.1
Gerando a classe C# a partir do arquivo .proto
protoc --proto_path=<pasta_protos> --csharp_out=<pasta_de_saída> nome_do_arquivo.proto
cd c:/repos/projeto
protoc --proto_path=protos/ --csharp_out=Sincronizador/Modelos/ Produto.proto
Como utilizar a classe .cs gerada
Install-Package Google.Protobuf -Version 3.6.1
//instanciando um objeto PhoneNumber e Person
var phoneNumber = new PhoneNumber
{
Number = "(11) 12345-6789",
Type = PhoneType.Mobile
};
var person = new Person()
{
Name = "Lazaro",
Id = 123,
Email = "[email protected]",
Phone = phoneNumber
};
//serializando o objeto
File.WriteAllBytes("person123_file", person.ToByteArray());
//deserializando o objeto
var person_fromfile = new Person();
person_fromfile.MergeFrom(File.ReadAllBytes("person123_file"));
message Test1 {
optional int32 a = 1;
}
```
```
var message = new Test1 {
a = 150
}
File.WriteAllBytes("test1", message.ToByteArray());
08 96 01
Por que não usar apenas XML ou JSON?
- estruturas `.proto` são simples, principalmente para estruturas com poucas propriedades, conforme visto no post.
- são de 3 a 10 vezes menores em tamanho
- são de 20 a 100 vezes mais rápidas na serialização/deserialização
- geram classes de fácil utilização pela aplicação
Comparação com Serialização em JSON
Criei um projeto simples para testar o cenário de serialização entre protoc e JSON aqui neste github. Você pode baixar o projeto e rodar localmente, aproveite para testar outros objetos e outras estratégias.
O resultado mostrou que a performance do protoc é exponencialmente maior que a da serialização em JSON, mesmo que os dois formatos estejam serializando para um array de bytes. Vejam o gráfico com o compilado dos resultados.
Lazaro Fernandes Lima Suleiman
Desenvolvedor