42d2900df9edad20092252cd6e3d2e7a8f788b2d
Notes App — Flutter + Go + gRPC (Protobuf)
Fullstack приложение-пример: единая типизация между Flutter фронтендом и Go бекендом через Protocol Buffers.
Структура
.
├── proto/ # ЕДИНЫЙ ИСТОЧНИК ПРАВДЫ
│ ├── notes/v1/notes.proto # Типы + API контракт
│ ├── buf.yaml # Конфиг Buf (линтинг, deps)
│ └── buf.gen.yaml # Конфиг кодогенерации
│
├── backend/ # Go gRPC сервер
│ ├── main.go # Точка входа, запуск gRPC
│ ├── service/note_service.go # Реализация NoteService
│ └── gen/notes/v1/ # Сгенерированный Go код
│ ├── notes.pb.go # Структуры (Note, Request, Response)
│ └── notes_grpc.pb.go # gRPC интерфейсы и регистрация
│
├── frontend/ # Flutter приложение
│ └── lib/
│ ├── main.dart # Точка входа
│ ├── screens/notes_screen.dart
│ ├── services/grpc_client.dart
│ └── gen/notes/v1/ # Сгенерированный Dart код
│ ├── notes.pb.dart # Классы (Note, Request, Response)
│ └── notes.pbgrpc.dart # gRPC клиент NoteServiceClient
│
└── generate.sh # Скрипт кодогенерации
Как это работает
notes.proto (единый контракт)
│
buf generate
┌─┴─┐
│ │
Go structs Dart classes
+ gRPC server + gRPC client
│ │
backend/gen frontend/lib/gen
- Все типы и API описаны в одном
.protoфайле - Из него генерируется типизированный код для обоих языков
- Изменил proto → перегенерировал → ошибки компиляции на той стороне, где контракт нарушен
- Невозможно отправить запрос с неверным типом — Dart не скомпилируется
- Невозможно вернуть ответ с неверной структурой — Go не скомпилируется
Быстрый старт
1. Запуск Go бекенда
cd backend
go run main.go
# → gRPC server listening on :50051
2. Запуск Flutter фронтенда
cd frontend
flutter run -d windows # или -d chrome, -d android и т.д.
3. Перегенерация кода (после изменения proto)
# Установи buf (один раз):
npm install -g @bufbuild/buf
# Генерация:
bash generate.sh
Или через protoc напрямую:
# Установи плагины (один раз):
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
dart pub global activate protoc_plugin
# Генерация:
bash generate.sh
Ключевая идея
Представь, что ты добавил новое поле priority в заметку:
message Note {
string id = 1;
string title = 2;
string content = 3;
google.protobuf.Timestamp created_at = 4;
google.protobuf.Timestamp updated_at = 5;
int32 priority = 6; // ← НОВОЕ ПОЛЕ
}
После buf generate:
- В Go:
note.Priorityдоступно сразу - В Dart:
note.priorityдоступно сразу - Оба языка знают о новом поле на этапе компиляции
- Если забыл его обработать — компилятор предупредит
Это аналог того, что Next.js делает для TS фронта/бека, но для разных языков.
Description
Languages
Dart
34.8%
C++
31.9%
CMake
17.5%
Go
6.7%
Shell
4.4%
Other
4.6%