gRPC-GoJuniorTechnical
Что такое Protocol Buffers (protobuf) и почему gRPC использует его вместо JSON?
Protocol Buffers — бинарный формат сериализации с компактным encoding по номерам полей. gRPC использует его для меньшего размера сообщений, быстрого парсинга и строгой типизации через .proto-схему.
Что такое Protocol Buffers
Protocol Buffers (protobuf) — язык описания схем данных и бинарный формат сериализации от Google. Схема описывается в .proto-файлах; инструмент protoc генерирует код для десятков языков. Каждое поле кодируется парой (номер поля, значение) без имён — это ключевое отличие от JSON.
Сравнение Protobuf vs JSON
- Размер: Protobuf в среднем в 3–10 раз меньше JSON. Поля кодируются varint-числами вместо строк.
- Скорость парсинга: бинарный формат парсится в 5–7 раз быстрее JSON; нет необходимости в лексере строк.
- Типизация: все типы строго определены в .proto; опечатки в именах полей — ошибка компиляции, а не runtime-баг.
- Эволюция схемы: поля идентифицируются по номерам, а не именам — переименование поля обратно совместимо.
- Читаемость: JSON читаем человеком без декодера; бинарный protobuf требует инструментов (protoscope, grpcurl).
Пример .proto и генерация Go-кода
syntax = "proto3";
package product;
option go_package = "example.com/gen/product";
message Product {
string id = 1;
string name = 2;
double price = 3;
repeated string tags = 4;
}
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
protoc --go_out=. --go-grpc_out=. product.proto
Использование сгенерированного кода
package main
import (
"fmt"
"log"
"google.golang.org/protobuf/proto"
pb "example.com/gen/product"
)
func main() {
p := &pb.Product{
Id: "sku-42",
Name: "Gopher Plush",
Price: 19.99,
Tags: []string{"toys", "go"},
}
// Сериализация
data, err := proto.Marshal(p)
if err != nil {
log.Fatal(err)
}
fmt.Printf("protobuf bytes: %d\n", len(data)) // ~25 байт
// Десериализация
var p2 pb.Product
if err := proto.Unmarshal(data, &p2); err != nil {
log.Fatal(err)
}
fmt.Println(p2.Name)
}
Обратная совместимость полей
// v2 — безопасное добавление поля
message Product {
string id = 1;
string name = 2;
double price = 3;
repeated string tags = 4;
string currency = 5; // новое поле — старые клиенты игнорируют
}
// НЕЛЬЗЯ: менять тип поля 3 с double на int64 — нарушает wire-совместимость
// НЕЛЬЗЯ: переиспользовать номер 3 для другого поля после удаления старого
Подводные камни
- Нельзя переиспользовать номера полей; удалённые поля следует помечать через
reserved 3;иreserved "price";. - Значения по умолчанию в proto3 (0, "", false) не отличимы от явно выставленных; используйте
optionalилиgoogle.protobuf.BoolValueдля явного null. - Бинарный формат не самодокументирован — без .proto-файла декодировать данные крайне сложно; храните схемы в Schema Registry.
- Изменение типа существующего поля (например,
int32→int64) нарушает wire-формат даже при совпадении имени. - JSON-транскодинг (grpc-gateway) преобразует proto в JSON по правилам camelCase — имя
user_idстанетuserId; фронтенд должен об этом знать. - Версия protoc и плагинов protoc-gen-go должна быть согласована во всей команде; разные версии могут генерировать несовместимый код.
proto.Cloneне копирует неизвестные поля корректно в некоторых версиях; для глубоких копий проверяйте поведение вашей версии SDK.
Common mistakes
- Давать ответ про protobuf и JSON в gRPC только на уровне определения, не показывая поведение в реальном приложении.
- Игнорировать границы ответственности вокруг темы «protobuf и JSON в gRPC»: кто отменяет работу, кто владеет ресурсом и где формируется ответ клиенту.
- Не связывать protobuf и JSON в gRPC с observability, тестированием или безопасностью, когда это влияет на продакшен-поведение.
What the interviewer is testing
- Точно объясняет, что именно делает protobuf и JSON в gRPC и где это используется в Go-коде.
- Связывает protobuf и JSON в gRPC с корректным lifecycle запроса, отменой, конкурентностью или конфигурацией сервера там, где это уместно.
- Не изобретает API и опирается на реальные контракты официальной документации.