# 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 ``` 1. Все типы и API описаны в одном `.proto` файле 2. Из него генерируется типизированный код для **обоих** языков 3. Изменил proto → перегенерировал → **ошибки компиляции** на той стороне, где контракт нарушен 4. Невозможно отправить запрос с неверным типом — Dart не скомпилируется 5. Невозможно вернуть ответ с неверной структурой — Go не скомпилируется ## Быстрый старт ### 1. Запуск Go бекенда ```bash cd backend go run main.go # → gRPC server listening on :50051 ``` ### 2. Запуск Flutter фронтенда ```bash cd frontend flutter run -d windows # или -d chrome, -d android и т.д. ``` ### 3. Перегенерация кода (после изменения proto) ```bash # Установи buf (один раз): npm install -g @bufbuild/buf # Генерация: bash generate.sh ``` Или через protoc напрямую: ```bash # Установи плагины (один раз): 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` в заметку: ```protobuf 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 фронта/бека, но для **разных языков**.