gRPC-cервис, который позволяет проходить квизы на технические темы. к нему.
Сервис лежит в папке server.
Клиент к нему в виде Telegram бота в папке tg_client.
Сервис помимо gRPC ручек, имеет также http-proxy к ним.
Вопросы берутся из quizapi. Данный API, к сожалению, не позволяет получать конкретные вопросы, но он может предоставить пак рандомных вопросов по тегу или по категории. Вопросы сохраняются в базу сервиса, чтобы в конце концов их украсть и не ходить туда больше, ибо долго (около 300-400 мс).
- GO:
- minimock - моки для тестирования
- testify - удобнее писать тесты
- куча разного про gRPC: protobuf, grpc-gateway, genproto, grpc
- zap - пакет для логгирования от Uber
- pgx - для работы с Postgres
- yaml - чтение конфигов
- Postgres: хранение данных на стороне сервиса (пользователи, квизы, сессии)
- Goose: инструмент миграций
- Redis: хранение сессий пользователей на стороне ТГ-клиента
- Docker: контейнеризация сервиса и клиента, запуск
Созданный сервис позволяет:
- /api/adduser/{Name} - добавить пользователя в сервис (подробнее об упрощенной аутентификации ниже)
- /api/getquizlist - получить список квизов
- /api/addparty - запустить квиз-пати (принять участие в квизе, будет создана сессия и отправлены вопросы с вариантами ответов)
- /api/addanswers - отправить ответы (по id квиз-пати) и получить отчет по прохождению и место в рейтинге
- /api/getquiztop/{UserID}/{QuizID} - получить топ по квизу и свой рейтинг в нем
- /api/getglobalquiztop/{ID} - Просто получить топ по квизу (без привязки к пользователю)
Приличный сервис должен иметь хотя бы "упрощенную" систему авторизации/аутентификации. Поэтому было решен добавлять пользователя по некому токену, который сам пользователь присылает, а в ответ отправлять ему внутренний id этого пользователя в сервисе. Дальнейший доступ происходил по этому id. Соответственно, не может быть двух пользователей с одинаковыми токенами. Как и возможности восстановить доступ к аккаунту пользователя, ибо этого не предусмотрено. Увы. Однако, есть планы по улучшению этого функционала.
Сервис считывает параметры для запуска из переменных среды.
Также сервису необходим ключ к quizapi и список доступных клиентов для базовой аутентификации (сама базовая аутентификация клиентов пока не реализована, но тоже в планах). Конфиг передается по флагу --config, пример файла есть в network_config.yaml.
У клиента практически идентичные параметры для запуска, только ключ для Telegram бота, и данные по этому клиенту для базовой аутентификации.
Для запуска:
docker compose up --build
Это был первый микросервис который я написал (а также первый серьезный проект на Go), возможно слишком он слишком монолитный). Можно распилить на несколько сервисов, например, с пользователями, квизами, рейтингом. Последний особенно нужен, ибо сейчас все результаты хранятся в реляционном виде в postgres, и запрос там монструозный на вытаскивание рейтинга, что не круто (особенно с учетом того, что логика на стороне запроса, а не гошки).
Использовал Clean Architecture (где додумался) и TDD (часть ручек покрыта тестами на го с использованием моков, но далеко не вся, надо доделать).
- Эксплуатация и репозиторий
- DONE. Задеплоить бы...
- Разобраться с кодогенарцией (protoc, gateway, swagger). С protoc все понятно, надо просто в мейкфайл добавить, а вот gateway сломался, либо из-за изменений в нем самом, либо из-за перехода с винду на убунту, второй раз сгенерировать не могу.
- Запуск без докера (просто команды в мейкфайле)
- DONE. Обновить README
- DONE. Добавить gracefull shutdown
- DONE. Засунуть TG-клиент в докер
- DONE. Перейти на монорепу
- Аутентификация
- DONE. Добавить конфиги и их чтение для базовой аутентификации
- DONE. Аутентификация gRPC-канала с помощью TLS
- DONE. азовая аутентификация вызовов - логин и пароль у клиента, на стороне сервиса список доступных клиентов, проверка каждого вызова
- Улучшения/фиксы
- DONE. Порефакторить конфиги
- DONE. Пофиксить ручку AddUser на сервере
- DONE. Перевести ТГ-клиент на Redis
- DONE. Нормальные кнопки в ТГ-клиенте, а не это безобразие
- Добавить метрики (например, по времени запроса в апишку с квизами, количеству новых вопросов оттуда и др.)
- Брать квизы из конфиг файла (сейчас захардкожено в миграцию, ручки у апишки нет, чтобы достать возможные темы, см. следующее)
- DONE. Сделать скрипт, который вытягивает вопросы, теги и категории из апишки с вопросами
- Переписать обработку запросов сервера на стороне го, а не постгри
- Переделать добавление пользователя в систему (ручка AddUser) (хранить информацию об используемом клиенте и никнейме участника, чтобы они не пересекались и были ники на стороне сервиса)
- DONE. Есть подозрение, что сейчас конфиги зашиты в докерфайлы, и чтобы прокинуть новые, надо пересобирать, не круто, вообще не круто
- Тесты
- Дописать юнит-тесты на ручки
- Написать e2e тесты на питоне с использованием фейк-базы
- Провести нагрузочное тестирование
- Написать тесты на ТГ-клиент