Как перестать страдать с Protobuf и начать жить

16 Jul, 2026
11,291
🔱 363
👥 70

Если вы хоть раз настраивали генерацию кода из .proto файлов в крупном проекте, то наверняка помните этот специфический ритуал. Нужно установить protoc правильной версии, не забыть про плагины для нужного языка, прописать километровые пути в --proto_path и надеяться, что у коллеги в CI стоит точно такое же окружение. А когда кто-то из команды случайно меняет тип поля в общем контракте и ломает обратную совместимость, об этом узнаешь уже на этапе рантайма.

The Buf logo

Проект buf появился как попытка превратить работу с Protocol Buffers из набора костылей в нормальный, предсказуемый процесс. Разработчики из Bufbuild решили, что Protobuf — это отличная база для API, но инструменты вокруг него застряли в прошлом десятилетии.

Что не так с обычным подходом

Стандартный компилятор protoc делает ровно то, для чего создан: компилирует файлы. Он не умеет проверять стиль именования, не следит за тем, чтобы вы не удалили важное поле из структуры, и заставляет вас вручную управлять зависимостями. Если у вас два микросервиса используют общие типы, вам приходится либо копипастить файлы, либо городить сложные скрипты с git submodules.

Buf заменяет собой эту чехарду. Это CLI-инструмент, который берет на себя всё: от форматирования кода до проверки совместимости версий.

Четыре вещи, которые делают жизнь проще

1. Линтер, который понимает API

Обычно правила именования в Protobuf держатся на честном слове или ревью. Buf проверяет структуру файлов автоматически. Если вы назвали поле в snake_case, а в проекте принято другое, или забыли указать пакет — линтер выдаст ошибку с точным указанием строки. В нем зашито около 40 правил, которые помогают держать API в чистоте.

2. Детектор ломающих изменений

Это, пожалуй, самая полезная фича для командной разработки. Команда buf breaking сравнивает текущую версию ваших .proto файлов с предыдущей (например, из ветки main или конкретного git-тега). Если вы изменили номер тега у поля или удалили поле, которое еще используется, Buf просто не даст пройти проверку в CI. Это избавляет от ситуаций, когда обновленный сервис «кладет» старых клиентов.

3. Генерация кода без боли

Вместо того чтобы писать огромные bash-скрипты с вызовами protoc, вы создаете один конфиг buf.gen.yaml. Там описываются нужные плагины (Go, Java, TypeScript и так далее) и пути вывода. Дальше достаточно запустить buf generate. Инструмент сам найдет все файлы, разрулит импорты и вызовет генераторы.

4. Умное форматирование

Команда buf format работает как gofmt или prettier. Она приводит все файлы к единому стандарту. Больше никаких споров о том, сколько пробелов ставить в отступах и где должна находиться открывающая фигурная скобка.

Техническая сторона вопроса

Интересно, что Buf не просто обертка над protoc. Внутри у него собственный компилятор, написанный на Go. Разработчики утверждают, что он работает быстрее оригинала за счет параллельной обработки файлов на всех ядрах процессора. На практике это дает почти мгновенный фидбек при сохранении файла в IDE.

Кстати, об IDE. У проекта есть плагины для VS Code и JetBrains (IntelliJ, GoLand). Они подсвечивают ошибки линтера прямо в процессе написания кода, так что вам не нужно ждать запуска тестов, чтобы увидеть опечатку в названии сервиса.

Как это использовать на практике

Представьте, что у вас есть репозиторий с контрактами микросервисов. Раньше вам приходилось скачивать protoc, искать плагины и мучиться с путями. С Buf процесс выглядит так:

  1. Ставите утилиту через brew install bufbuild/buf/buf (или через npm/docker).
  2. Создаете файл buf.yaml в корне с описанием проекта.
  3. Настраиваете CI, чтобы при каждом пуше запускался buf lint и buf breaking --against '.git#branch=main'.

Если вы хотите пойти дальше, у ребят есть Buf Schema Registry (BSR). Это что-то вроде Docker Hub или npm, но для Protobuf-схем. Можно публиковать свои модули туда, и другие сервисы смогут подтягивать их как зависимости, не копируя файлы к себе.

Стоит ли переходить

Buf определенно пригодится, если:

  • В вашем проекте больше пяти .proto файлов и над ними работает несколько человек.
  • Вы устали от того, что в разных сервисах поля называются то user_id, то UserID.
  • Вам нужно гарантировать, что обновление API не сломает мобильное приложение или фронтенд.

Для совсем маленьких пет-проектов на один сервис это может быть оверкиллом, но как только появляется взаимодействие между компонентами, Buf экономит кучу нервов. Главный плюс в том, что его можно внедрять постепенно: сначала просто как форматер, потом добавить линтер, и только затем перевести на него генерацию кода.

Единственный нюанс — нужно привыкнуть к их модели конфигурации, которая немного отличается от классического подхода Google. Но документация у проекта подробная, а туториал проходится за 10-15 минут.

Если вы работаете с gRPC или просто используете Protobuf для сериализации, попробуйте хотя бы запустить линтер на своих текущих файлах. Результаты могут вас удивить.

🍪 Мы используем файлы cookie и сервис аналитики Яндекс.Метрика, чтобы сайт работал лучше. Продолжая пользоваться devtrends.ru, вы соглашаетесь с обработкой данных согласно Политике конфиденциальности.