// desktop only

Презентации лучше смотреть с десктопа

Слайды рассчитаны на широкий экран, клавиатуру и формат 16:9. Откройте эту страницу на ноутбуке или компьютере.

Вернуться на сайт
// доклад · protobuf · ecosystem

EasyP:
или как переизобрести prototool?

Эдгар Сипки//Developer Advocate MWS

// speaker.bio

Эдгар Сипки

Developer Advocate MWS · @zergslaw
  • НЕгений, НЕмиллиардер, НЕфилантроп
  • Евангелист gRPC
  • Фанат War / Craft / Hammer
// agenda

О чём поговорим?

  1. 01Что такое protobuf?
  2. 02Как расширяется proto?
  3. 03Toolset для работы с proto
  4. 04Берём всё в свои руки
// chapter 01

ЧТО ТАКОЕ
PROTOBUF?

// protobuf.intro

Что такое Protobuf?

01

Бинарный формат

Меньше размер по сравнению с JSON и XML, быстрее парсится.

02

Строгая типизация

Использует схемы (.proto файлы) для определения структуры сообщений.

03

Обратная совместимость

Позволяет эволюционировать API без нарушения работы существующих клиентов.

// grpc.intro

Что такое gRPC?

[G]

Разработан Google

[P]

Protobuf-сериализация

[</>]

Кодогенерация

[H/2]

HTTP/2 транспорт

// extensibility

Расширяется плагинами

01

Гибкая архитектура

Поддерживает модули для расширения функциональности.

02

Кодогенерация

Плагины генерируют код на разных языках.

03

Ускорение разработки

Валидация, документация, тестирование — из коробки.

04

Свои плагины

Собственные расширения под задачи команды.

// philosophy

SPEC
FIRST

  • Спека — истина, ваш код — тоже истина
  • Не получаем рассинхрон кода и документации
// agenda

О чём поговорим?

  • Что такое protobuf?
  • Как расширяется proto?
  • Toolset для работы с proto
  • Берём всё в свои руки
// chapter 02

КАК РАСШИРЯЕТСЯ
PROTO?

// buf.gen.yaml

Плагины для protoc

plugins:
  - name: go
    out: .
    opts:
      paths: source_relative
  - name: go-grpc
    out: .
    opts:
      paths: source_relative
      require_unimplemented_servers: false
// libraries

Официальные и
популярные библиотеки

google.golang.org/protobuf/compiler/protogen

Стандартная библиотека от Google.

github.com/lyft/protoc-gen-star

Комьюнити-вариант с удобной обёрткой над AST.

// main.go

main.go

protogen.Options{
    ParamFunc: flag.CommandLine.Set,
}.Run(func(gp *protogen.Plugin) error {
    gp.SupportedFeatures = uint64(pluginpb.CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL)

    for _, name := range gp.Request.FileToGenerate {
        glog.V(1).Infof("Processing %s", name)
        glog.V(2).Infof("Generating %s\n", fmt.Sprintf("%s.pb.json.go", f.GeneratedFilenamePrefix))

        gf := gp.NewGeneratedFile(fmt.Sprintf("%s.pb.mocker.go", f.GeneratedFilenamePrefix), f.GoImportPath)

        err := templates.ApplyTemplate(gf, f)
        ...
    }

    return nil
})
// apply.go

Собираем вызовы

func ApplyTemplate(w io.Writer, f *protogen.File) error {
    if err := headerTemplate.Execute(w, tplHeader{
        File: f,
    }); err != nil {
        return err
    }

    return applyMessages(w, f.Messages)
}
// header.go

Headers

type tplHeader struct {
    *protogen.File
}

var headerTemplate = template.Must(template.New("header").Parse(`
// Code generated by protoc-gen-mocker. DO NOT EDIT.
// source: {{.Proto.Name}}

package {{.GoPackageName}}

import (
    "go.uber.org/mock/gomock"
    "google.golang.org/protobuf/proto"
)

var _ gomock.Matcher
`))
// messages.go

Messages

type tplMessage struct {
    *protogen.Message
}

var messageTemplate = template.Must(template.New("message").Parse(`

// Matches implements gomock.Matcher.
func (msg *{{.GoIdent.GoName}}) Matches(y interface{}) bool {
    p2, ok := y.(proto.Message)
    if !ok {
        return false
    }

    return proto.Equal(msg, p2)
}
`))
// buf.gen.yaml

Вызов

plugins:
  - name: go
    out: .
    opts:
      paths: source_relative
  - name: go-grpc
    out: .
    opts:
      paths: source_relative
      require_unimplemented_servers: false
  - name: mocker
    out: .
    opts:
      paths: source_relative
// agenda

О чём поговорим?

  • Что такое protobuf?
  • Как расширяется proto?
  • Toolset для работы с proto
  • Берём всё в свои руки
// chapter 03

TOOLSET
ДЛЯ PROTO

// pain.txt

Проблемы proto?

  • Отсутствие встроенного пакетного менеджера
  • Разнообразие стилей
  • Лёгкая возможность поломать обратную совместимость
  • Неудобство в генерации (ох уж эти 10-строчные bash-команды)
// uber/prototool

Prototool

README.md

Update: We recommend checking out Buf, which is under active development. There are a ton of docs for getting started, including for migration from Prototool.

License: MIT · v1.10.0 · last release: 5 years ago

// protop

Protop

gradlew.bat       What: executable task created.   5 years ago
install.sh        Feature/Registry (#24)           5 years ago
settings.gradle   init                             5 years ago

Apache-2.0 · последний коммит — 5 лет назад.

Да кто это такой
ваш Buf?

// bufbuild/buf

Единственный выживший?

  • Linter
  • Package manager
  • Breaking checker
  • Generator
Buf
all-in-one для proto

Это всё что ли?

// status

Но нас заблокировали

  • Linter
  • Package manager
  • Breaking checker
  • Generator

Часть функционала недоступна из РФ.

// agenda

О чём поговорим?

  • Что такое protobuf?
  • Как расширяется proto?
  • Toolset для работы с proto
  • Берём всё в свои руки
// chapter 04

БЕРЁМ ВСЁ
В СВОИ РУКИ

// reality.check

Нам нужно работать

  • Локально на VPN
  • CI/CD поломан
  • Перевезти целый BigTech не легко
// guest #1

Даниил Подольский

  • Нужно срочное решение
  • Перевезти на что-то своё быстро нельзя
  • Блокировка многих мест
  • Велосипед?
role
ENGINEER
status: in_progress
// architecture.flow

Архитектура package manager

Client      CLI         ResolveSvc   RepositorySvc   DownloadSvc
  |          |              |             |               |
  |--Request->              |             |               |
  |          |--Resolve---->|             |               |
  |          |<--repo-addr--|             |               |
  |          |--Get repo info------------>|               |
  |          |<--repo info----------------|               |
  |          |--Download------------------------>         |
  |          |<--files------------------------------------|
  |<-Packages-|              |             |               |
// easyp.yaml

URL до нашего сервера

deps:
  - <your_host>/googleapis/googleapis
  - <your_host>/bufbuild/protoc-gen-validate
// why.md

Почему так?

  • Разблокировали большую часть процесса
  • Не пришлось перевозить сотрудников (оставили им buf)
  • Быстро
// guest #2

Василий Близнецов

Open Source должен быть для всех.

  • Не хотели сидеть на buf дальше
  • Хотели механизм, не позволяющий блокировать
  • Любим велосипеды
role
CO-FOUNDER
status: open_source
// mission

ВИЖУ ЦЕЛЬ —
ИДУ К ЦЕЛИ

// roadmap

Должны не повторить,
а улучшить

// first_target

Package manager

// go get

Как работает go get?

[ go get command ] -> [ Git repo URL ] -> [ Fetch package ] -> [ Save locally ] -> [ Update lock file ]
// implementation

Это не шутка

os.Exec("git", ...)
git init --bare
git fetch --depth=1
git ls-tree
git archive --format=zip
# и всё! (ну почти)
// easyp.yaml

Полная
совместимость (ну почти)

deps: [
  github.com/googleapis/googleapis,
  github.com/grpc-ecosystem/grpc-gateway@v2.1.4,
  github.com/bufbuild/protoc-gen-validate@<hash_commit>,
]
// easyp.lock

easyp.lock

github.com/bufbuild/protoc-gen-validate   v1.1.1
github.com/googleapis/googleapis          v0.0.0-202411...
github.com/grpc-ecosystem/grpc-gateway    v0.0.0-...
// agenda

О чём поговорим?

  • Что такое protobuf?
  • Как расширяется proto?
  • Toolset для работы с proto
  • Берём всё в свои руки
// outro

Так чего в итоге?

  • Не боимся делать проблем — они дают возможность (АУФ)
  • Любим gRPC — он удобен
  • Пилим свои плагины и расширяем свою экосистему

easyp.tech · github.com/easyp-tech