Protocol buffers, protobuf ou simplesmente proto, é uma linguagem criada pela Google para serialização de dados. Para facilitar o entendimento, podemos comparar o protobuf com XML ou JSON. No entanto, dados serializados com proto, são MUITO menores quando comparados com as outras duas tecnologias.
Outro ponto importante é que, após escrever um arquivo proto, utilizamos um programa chamado protoc
para gerar código em Go, Java, Python, C#, C, C++, entre outras linguagens. Código esse que contém todas as classes e métodos que estiverem declarados dentro dos arquivos proto.
Mas calma! Antes de falar mais sobre esse código gerado, vamos entender o que compõe e como criar um arquivo proto.
Syntax
A primeira coisa que precisamos fazer em um arquivo proto é definir sua syntax. Essa syntax nada mais é do que a versão do protobuf que iremos utilizar.
Atualmente existem duas versões, proto2 e proto3, sendo a segunda a mais recente.
syntax = "proto3";
Package
Embora não seja obrigatório, para evitar possíveis problemas de conflitos de nomes, podemos declarar um nome para nosso package.
syntax = "proto3"; package products;
Ao gerar o código com protoc
, o nome definido será utilizado como package ou namespace da linguagem.
Ainda podemos definir nomes específicos para cada linguagem, como podemos ver no exemplo abaixo.
sytax = "proto3"; package products; option go_package = "products"; option java_package = "br.com.products"; option csharp_namespace = "Products";
Message
Agora que definimos a syntax e o nome do package, vamos ver o que são as “messages”.
A maneira mais fácil para compreende-las, é pensar nelas como sendo classes, somente com atributos, e que serão utilizadas para transportar dados entre serviços.
message Category { optional int32 id = 0; string name = 1; optional string description = 2; bool is_active = 3; }
No exemplo acima, declaramos uma mensagem do tipo Category. Como você pode ver, antes de cada um dos atributos, definimos o seu tipo. No caso do id e da description, utilizamos também a palavra reservada optional
, que torna esses atributos opcionais, ou seja, não é preciso passar nenhuma valor. Caso nenhum valor seja informado, ao construir a classe ou struct, o valor default do tipo será atribuído.
Logo após o nome dos atributos, definimos um valor numérico que será utilizado para a serialização dos dados.
Para ficar mais claro a finalidade desses valores numéricos, imagine que, para reduzir o tamanho dos dados trafegados, uma mensagem proto serializada, ao invés de trafegar {"name": "Suspense"}
, irá trafegar algo como {1: "Suspense"}
.
Isso é possível pois, no código gerado com protoc
, existem referências entre os valores numéricos e o nome dos atributos.
Além dos tipos básicos, também podemos utilizar uma mensagem como tipo de um atributo.
message Item { int32 id = 0; string name = 1; int32 qtdy = 2; float unit_price = 3; float total = 4; } message Cart { repeated Item items = 0; float subtotal = 1; float discount = 2; float total = 3; }
Como um carrinho de compra pode ter vários itens, precisamos adicionar a palavra reservada repeated
antes de declarar o tipo do atributo.
Service
Por fim, um arquivo .proto
normalmente conterá um ou mais services.
service CategoryService { rpc Save(CategoryRequest) returns (CategoryResponse); rpc Find(CategoryFilterRequest) returns (CategoryListResponse); }
Esses services são utilizados para realizar comunicação entre aplicações via RPC (Remote Procedure Call).
Embora você possa implementar toda a comunicação via RPC por conta própria, a prática mais comum hoje em dia é utilizar algum framework pronto, como por exemplo, o gRPC. gRPC é um framework desenvolvido pela Google, hoje mantido pela CNCF, e funciona muito bem com protobuf.
O framework gRPC ainda conta com um plugin chamado [protoc-gen-go-grpc](<https://pkg.go.dev/google.golang.org/grpc/cmd/protoc-gen-go-grpc>)
. Esse plugin, quando utilizado em conjunto com o protoc
, gera código para o cliente e para o servidor.
Conclusão
Um post tão teórico como este provavelmente não te deu a real noção do poder de se utilizar protocol buffers.
No próximo post, vou trazer uma implementação prática de um serviço gRPC com protobuf.
Para não perder nada, não deixe de assinar nossa newsletter.
Até a próxima!
Parabéns pelo o artigo. Se encontra poucos artigos em português referente ao portobuffer.
[…] continuidade ao post o que é e como utilizar protobufs, nesse post, vamos colocar o conhecimento teórico em prática e fazer uma API utilizando protobuf […]