Skip to content

Service allowing to manage and show banners, depending on the required user's feature and tag.

Notifications You must be signed in to change notification settings

pavlegich/banners-service

Repository files navigation

Сервис баннеров

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

Описание задачи

Необходимо реализовать сервис, который позволяет показывать пользователям баннеры, в зависимости от требуемой фичи и тега пользователя, а также управлять баннерами и связанными с ними тегами и фичами.

Общие вводные

Баннер — это документ, описывающий какой-либо элемент пользовательского интерфейса. Технически баннер представляет собой  JSON-документ неопределенной структуры.  Тег — это сущность для обозначения группы пользователей; представляет собой число (ID тега).  Фича — это домен или функциональность; представляет собой число (ID фичи).  

  1. Один баннер может быть связан только с одной фичей и несколькими тегами
  2. При этом один тег, как и одна фича, могут принадлежать разным баннерам одновременно
  3. Фича и тег однозначно определяют баннер

Так как баннеры являются для пользователя вспомогательным функционалом, допускается, если пользователь в течение короткого срока будет получать устаревшую информацию. При этом существует часть пользователей (порядка 10%), которым обязательно получать самую актуальную информацию. Для таких пользователей нужно предусмотреть механизм получения информации напрямую из БД.

Условия

  1. Используется этот API.
  2. Тегов и фичей небольшое количество (до 1000), RPS — 1k, SLI времени ответа — 50 мс, SLI успешности ответа — 99.99%.
  3. Для авторизации доступов должны использоваться 2 вида токенов: пользовательский и админский. Получение баннера может происходить с помощью пользовательского или админского токена, а все остальные действия могут выполняться только с помощью админского токена.  
  4. Реализовать интеграционный или E2E-тест на сценарий получения баннера.
  5. Если при получении баннера передан флаг use_last_revision, необходимо отдавать самую актуальную информацию. В ином случае допускается передача информации, которая была актуальна 5 минут назад.
  6. Баннеры могут быть временно выключены. Если баннер выключен, то обычные пользователи не должны его получать, при этом админы должны иметь к нему доступ.

Дополнительные задания

  1. Адаптировать систему для значительного увеличения количества тегов и фичей, при котором допускается увеличение времени исполнения по редко запрашиваемым тегам и фичам.
  2. Провести нагрузочное тестирование полученного решения и приложить результаты тестирования к решению.
  3. Иногда получается так, что необходимо вернуться к одной из трех предыдущих версий баннера в связи с найденной ошибкой в логике, тексте и т.д. Измените API таким образом, чтобы можно было просмотреть существующие версии баннера и выбрать подходящую версию.
  4. Добавить метод удаления баннеров по фиче или тегу, время ответа которого не должно превышать 100 мс, независимо от количества баннеров. В связи с небольшим временем ответа метода, рекомендуется ознакомиться с механизмом выполнения отложенных действий.
  5. Реализовать интеграционное или E2E-тестирование для остальных сценариев.
  6. Описать конфигурацию линтера.

Требования по стеку

  • Язык сервиса: предпочтительным будет Go. 
  • База данных: предпочтительной будет PostgreSQL. 
  • Для деплоя зависимостей и самого сервиса рекомендуется использовать Docker и Docker Compose.

Ход решения

Возникающие вопросы по заданию, ответов на которые нет в описанных «Условиях», указать в приложенном к проекту README-файл, в котором будет список вопросов и пояснения о том, как получилось решить проблему и почему именно таким способом.

Оформление решения

Необходимо предоставить публичный git-репозиторий на любом публичном хосте (GitHub / GitLab / etc), содержащий в master/main ветке:

  1. Код сервиса.
  2. Makefile c командами сборки проекта / Описанная в README.md инструкция по запуску.
  3. Описанные в README.md вопросы/проблемы, с которыми столкнулись, и логика их решений (если требуется).

Запуск

Вывести список всех возможных команд:

make help

Запустить приложение локально:

make run-local

Запустить приложение с помощью docker-compose:

make run-docker

Сформировать документацию:

make doc

Note

Изменить значения флагов:

  • для локального запуска - в первых строках Makefile;
  • для запуска с помощью docker-compose - в файле .env.

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

  1. При GET запросе /banner в требованиях к API не указана возвращаемый ответ 400 (Bad Request). Так как в query может быть указано некорректное значение, добавил этот ответ в свой сервис.

  2. Описание примеров запросов в Postman содержится в banners-service.json.

  3. Интеграционные тесты расположены в файле internal/domains/banner/controllers/http/user_test.go.

  4. Использован линтер (golangci-lint) для анализа кода и предотвращения появления разного рода ошибок в ходе его написания. Выбран golangci-lint, так как он включает в себя сразу пакет необходимых линтеров, поддерживает удобную конфигурацию. Из проверки исключены функции w.Write (запись данных в ответ сервера) и logger.Log.Sync (очистка записей журнала логгера перед выходом из приложения).

About

Service allowing to manage and show banners, depending on the required user's feature and tag.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages