Общие пакеты (pkg/)¶
Директория pkg/ содержит переиспользуемые пакеты, которые разделяются между микросервисами монорепозитория Univex. Каждый пакет решает одну конкретную задачу и не имеет бизнес-логики. Всего 15 пакетов.
balogan/¶
Путь: pkg/balogan/
Назначение: Пакет структурированного логирования. Предоставляет единый интерфейс логгера для всех сервисов монорепозитория.
Ключевые возможности:
- Структурированные поля (key-value) в каждой записи лога
- Уровни:
Debug,Info,Warn,Error - Интеграция с контекстом (
context.Context) для передачи trace/correlation ID - Настраиваемый формат вывода (JSON для продакшена, текст для разработки)
Пример:
import "pkg/balogan"
logger := balogan.New(balogan.Config{Format: "json", Level: "info"})
logger.Info(ctx, "trade saved",
balogan.Field("ticker", trade.Ticker),
balogan.Field("price", trade.Price),
balogan.Field("exchange_time", trade.ExchangeTime),
)
clients/¶
Путь: pkg/clients/
Назначение: HTTP/gRPC-клиенты для взаимодействия с внешними и внутренними сервисами.
Содержит два подпакета:
clients/exchange/¶
HTTP-клиент для взаимодействия с Exchange HTTP API. Используется сервисом Trades Aggregator для получения торговых данных.
- Получение списка торгов за временной диапазон
- Поддержка фильтрации по торговым парам (тикерам)
- Retry-логика при временных сбоях
- Настраиваемые таймауты и заголовки аутентификации
import "pkg/clients/exchange"
client := exchange.NewClient(exchange.Config{
BaseURL: "https://exchange.example.com",
APIKey: "...",
Timeout: 10 * time.Second,
})
trades, err := client.GetTrades(ctx, exchange.GetTradesParams{
Ticker: "BTC_USDT",
From: time.Now().Add(-time.Hour),
To: time.Now(),
})
clients/apigen/¶
OpenAPI-сгенерированный клиент для Exchange HTTP API. Содержит типы запросов/ответов на основе OpenAPI-спецификации. Используется как зависимость для clients/exchange/. Не предназначен для ручного редактирования.
deps/¶
Путь: pkg/deps/
Назначение: Вспомогательные функции для организации инъекции зависимостей (Dependency Injection). Упрощает сборку компонентов сервиса.
Ключевые возможности:
- Базовые интерфейсы для объявления зависимостей
- Вспомогательные функции для инициализации с обработкой ошибок
- Паттерн
MustProvide— паника при невозможности создать зависимость (используется при старте сервиса)
import "pkg/deps"
// При старте сервиса: паника при ошибке конфигурации
db := deps.MustProvide(func() (*sqlx.DB, error) {
return sqlx.Connect("postgres", cfg.DatabaseURL)
})
find/¶
Путь: pkg/find/
Назначение: Вспомогательные функции для поиска элементов в коллекциях и структурах данных. Обобщённые утилиты для типичных задач поиска без написания повторяющегося кода.
hawk/¶
Путь: pkg/hawk/
Назначение: Утилиты для обработки ошибок. Предоставляет удобные обёртки для создания, оборачивания и проверки ошибок в Go, совместимые со стандартным интерфейсом error.
jsonify/¶
Путь: pkg/jsonify/
Назначение: Вспомогательные функции для работы с JSON. Упрощает типичные операции сериализации/десериализации и устраняет повторяющийся boilerplate-код.
Ключевые возможности:
Marshal(v any) ([]byte, error)— сериализация в JSONUnmarshal(data []byte, v any) error— десериализация из JSONMustMarshal(v any) []byte— сериализация с паникой при ошибке (для тестов/констант)- Поддержка prettified вывода для отладки
metrics/¶
Путь: pkg/metrics/
Назначение: Интеграция с Prometheus для сбора метрик. Предоставляет единый способ регистрации и экспорта метрик из всех сервисов монорепозитория.
Ключевые возможности:
- Регистрация счётчиков, гистограмм, gauge
- HTTP-эндпоинт
/metricsдля Prometheus scrape - Предустановленные метрики для gRPC (latency, error rate)
mocks/¶
Путь: pkg/mocks/
Назначение: Тестовые моки для gRPC-клиентов и внутренних интерфейсов. Используются в unit-тестах сервисов для изоляции зависимостей.
pointer/¶
Путь: pkg/pointer/
Назначение: Вспомогательные функции для работы с указателями на примитивные типы Go. Устраняет boilerplate при создании указателей на литеральные значения.
Ключевые функции:
// Возвращает указатель на переданное значение
func To[T any](v T) *T
// Возвращает значение указателя или дефолтное, если указатель nil
func FromOrDefault[T any](p *T, def T) T
// Проверяет, что указатель не nil и возвращает значение
func From[T any](p *T) (T, bool)
Пример:
import "pkg/pointer"
req := &SomeRequest{
Limit: pointer.To(100),
Offset: pointer.To(0),
Name: pointer.To("BTC_USDT"),
}
sha256/¶
Путь: pkg/sha256/
Назначение: Утилиты для хэширования на основе алгоритма SHA-256. Используется Exchange Integration для хэширования паролей перед сохранением в БД.
Ключевые возможности:
Hash(input string) string— вычисление SHA-256 хэша строки, возврат hex-представленияCompare(input, hash string) bool— сравнение строки с её хэшем (constant-time)
import "pkg/sha256"
hashed := sha256.Hash(req.Password)
// Сохранить hashed в БД
ok := sha256.Compare(req.Password, storedHash)
// ok == true если пароль совпадает
slicex/¶
Путь: pkg/slicex/
Назначение: Обобщённые утилиты для работы со срезами (дженерики Go 1.18+). Устраняет необходимость в повторяющемся коде при типичных операциях со срезами.
Ключевые функции:
// Фильтрация среза по предикату
func Filter[T any](slice []T, fn func(T) bool) []T
// Трансформация элементов среза
func Map[T, R any](slice []T, fn func(T) R) []R
// Проверка наличия элемента
func Contains[T comparable](slice []T, item T) bool
// Удаление дублей
func Unique[T comparable](slice []T) []T
// Разбиение на группы
func Chunk[T any](slice []T, size int) [][]T
sqlxtrm/¶
Путь: pkg/sqlxtrm/
Назначение: Управление SQL-транзакциями для sqlx. Предоставляет удобный паттерн для работы с транзакциями в PostgreSQL.
Ключевые возможности:
WithTransaction(ctx, db, fn)— выполнить функцию в транзакции с автоматическим commit/rollback- Поддержка вложенных транзакций через savepoint
- Интеграция с
context.Contextдля отмены транзакции
import "pkg/sqlxtrm"
err := sqlxtrm.WithTransaction(ctx, db, func(tx *sqlx.Tx) error {
if _, err := tx.ExecContext(ctx, insertQuery, args...); err != nil {
return err // автоматический rollback
}
if _, err := tx.ExecContext(ctx, updateQuery, args...); err != nil {
return err // автоматический rollback
}
return nil // автоматический commit
})
temporal/¶
Путь: pkg/temporal/
Назначение: Обёртки над Temporal.io SDK для упрощения работы с workflow и activity. Используется сервисами Ledger, P2P, UnivexID.
Ключевые возможности:
- Инициализация Temporal Worker с общей конфигурацией
- Базовые типы для регистрации workflow и activity
- Вспомогательные функции для запуска workflow с повторами
- Структуры конфигурации (адрес Temporal, namespace, очереди задач)
import "pkg/temporal"
worker := temporal.NewWorker(temporal.Config{
HostPort: "temporal:7233",
Namespace: "univex",
TaskQueue: "trades-aggregator",
})
worker.RegisterWorkflow(TradesFetchWorkflow)
worker.RegisterActivity(FetchTradesActivity)
if err := worker.Start(); err != nil {
log.Fatal(err)
}
utils/¶
Путь: pkg/utils/
Назначение: Общие утилиты, не вошедшие в специализированные пакеты. Вспомогательные функции для работы со строками, временем, UUID и другими базовыми типами.
validator/¶
Путь: pkg/validator/
Назначение: Утилиты для валидации входных данных в gRPC-хэндлерах и domain-слое.
Ключевые возможности:
- Валидация обязательных строковых полей (не пусто, не пробелы)
- Валидация UUID-идентификаторов
- Валидация числовых диапазонов (положительные значения, минимум/максимум)
- Валидация email-адресов и номеров телефонов
- Агрегация нескольких ошибок валидации в одну
import "pkg/validator"
func (s *Server) Register(ctx context.Context, req *pb.RegisterRequest) (*pb.RegisterResponse, error) {
if err := validator.ValidateAll(
validator.Required("account_id", req.AccountId),
validator.Required("password", req.Password),
validator.MinLen("password", req.Password, 8),
); err != nil {
return nil, status.Error(codes.InvalidArgument, err.Error())
}
// ...
}
Сводная таблица пакетов¶
| Пакет | Используется в | Назначение |
|---|---|---|
balogan |
Все сервисы | Структурированное логирование |
clients/exchange/ |
Trades Aggregator | HTTP-клиент Exchange API |
clients/apigen/ |
clients/exchange/ |
OpenAPI-сгенерированные типы |
deps |
Все сервисы | Инъекция зависимостей |
find |
Все сервисы | Утилиты поиска в коллекциях |
hawk |
Все сервисы | Обработка ошибок |
jsonify |
Все сервисы | JSON-утилиты |
metrics |
Все сервисы | Метрики Prometheus |
mocks |
Тесты | Тестовые моки |
pointer |
Все сервисы | Указатели на примитивные типы |
sha256 |
Exchange Integration | Хэширование паролей |
slicex |
Все сервисы | Обобщённые операции со срезами |
sqlxtrm |
Exchange Integration, Trades Aggregator, Ledger | Управление SQL-транзакциями |
temporal |
Ledger, P2P, UnivexID | Temporal workflow/activity обёртки |
utils |
Все сервисы | Общие утилиты |
validator |
Все сервисы | Валидация входных данных |