dynamic-content-service

module
v0.0.0-...-7543e54 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 14, 2024 License: MIT

README

banner-service

Сервис управления пользовательским динамическим контентом

В Авито есть большое количество неоднородного контента, для которого необходимо иметь единую систему управления. В частности, необходимо показывать разный контент пользователям в зависимости от их принадлежности к какой-либо группе. Данный контент мы будем предоставлять с помощью баннеров.

Задача

Реализовать сервис с одним пользовательским эндпойнтом, с помощью которого пользователям выдаются баннеры в зависимости от указанной группы и фичи, и несколькими админскими - для управления ими.

Что сделано

  • Имитация работы сервиса авторизации при помощи 2 видов токенов
  • Реализованы все эндпойнты из основной части задания
  • Кэширование в Redis для оптимизации пользовательских запросов
  • Выполнен интеграционный тест на сценарий получения баннера пользователем
  • Схема БД адаптирована для увеличения количества тегов и фичей, а также для компактного хранения версий
  • Два эндпойнта GET и PATCH для управления версиями баннеров
  • Метод удаления баннеров по фиче или тегу с использованием scheduled task
  • Документация swagger (находится в ./docs в json и yaml форматах)

Не выполнено

  • Нагрузочное тестирование - нет опыта с loadtesting, не уложился в сроки. Вернусь к этому вне рамок тестового, сделаю при помощи jmeter/grafana.
  • Не реализовано интеграционное или E2E-тестирование для остальных сценариев
  • Отсутствует конфигурация линтера

Описание решения

  • Go 1.22.1
  • База данных postgres: pgx toolkit
  • Redis
  • Окружение с docker-compose
  • Маршрутизация с помощью gorilla/mux
  • Валидация запросов go-playground/validator
  • Логирование при помощи zap
  • Тесты: testify/suite
  • Scheduled task: gocron

Возникшие вопросы и их решения

? Как реализовать авторизацию?

! Поскольку задание - это сервис контента, решил использовать метод, который будет только имитировать работу авторизации, поскольку обычно для этого реализуются отдельные сервисы. Для получения доступа к эндпойнтам требуется заголовок X-Access-Token. Существуют 4 префикса: aup - authorized user prefix и aap - authorized admin prefix для авторизированных юзера и админа соответсвенно. И два других uup и uap для неавторизованных. Все остальные будут получать 403 ответ на каждом эндпойнте.

? Как использовать условие с допуском выдачи баннера, актуального в течении 5 минут?

! Использовать кеширование ключей с TTL 5 минут. Первая идея была использовать memcached, поскольку было дано небольшое количество тегов и фичей. После дополнительного условия в виде значительного увеличения количества сущностей БД решил, что нужно отдельное хранилище и выбрал redis.

? Как более эффективно выполнять удаление из БД?

! "Помечать" удаленными вместо самого удаления и использовать запланированную задачу для очистки удаленных записей в дальнейшем. Для этого удобно использовать Cron. Поскольку такое единовременное удаление огромного количества записей будет сильно нагружать сервис, таска была установлена на выполнение во время ожидаемого простоя API.

? Как организовать управление версиями баннеров, чтобы можно было хранить три предыдущие и при необходимости вернуться к прошлым наполнением контента, связям с фичами, тегами?

! Версионирование можно было бы реализовать следующим образом: перенести все содержимое баннера в отдельную сущность, а в самом баннере хранить ссылку на версию. Сам же контент доставать по этой ссылке. Но тогда возникают проблемы. Баннер уже не будет центральной сущностью, какой он должен быть. А также возникает страшное количество дублирования данных - каждая версия связана с каждым тегом, которые могут быть ровно такими же, какими были для основного баннера. Я выбрал следующий подход: хранить версии как некий контекст для основного баннера: фича, контент, активен ли баннер, а также список тегов в виде строки, где они перечислены через разделитель. Когда администратор хочет вернуться к определенной версии, связи основного баннера перезатираются из версии, а все версии, что были после той, к которой он перешел - удаляются, поскольку хранят некорректную логику.

Инструкция по запуску

При запуске самого приложения добавляются 2000 тегов и фичей. Баннеры отсутствуют.

git clone git@github.com:mBayzigitov/dynamic-content-service.git
  • Запустить приложение (не занимая окно терминала)
make run

или в явном виде

make run-ex

чтобы пересобрать:

make run-rebuild

остановить контейнеры:

make stop

удалить контейнеры:

make down

удалить вместе с томами:

make down-v
  • Запустить интеграционные тесты (контейнеры останавливаются автоматически по окончании)
make test

удалить тестовые сервисы

make down-tests

Directories

Path Synopsis
Package docs Code generated by swaggo/swag.
Package docs Code generated by swaggo/swag.
internal
dto

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL