sellerx-task

module
v0.0.0-...-e384ca1 Latest Latest
Warning

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

Go to latest
Published: Jul 29, 2021 License: MIT

README

Тестовое задание SellerX

Содержание

  1. Описание задачи
  2. Реализация
  3. Архитектура
  4. Запуск
  5. Тестирование
  6. Документация
  7. Нагрузочное тестирование
  8. Примеры

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

Цель задания – разработать чат-сервер, предоставляющий HTTP API для работы с чатами и сообщениями пользователя.

Основные сущности

Ниже перечислены основные сущности, которыми должен оперировать сервер.

User

Пользователь приложения. Имеет следующие свойства:

  • id - уникальный идентификатор пользователя
  • username - уникальное имя пользователя
  • created_at - время создания пользователя
Chat

Отдельный чат. Имеет следующие свойства:

  • id - уникальный идентификатор чата
  • name - уникальное имя чата
  • users - список пользователей в чате, отношение многие-ко-многим
  • created_at - время создания
Message

Сообщение в чате. Имеет следующие свойства:

  • id - уникальный идентификатор сообщения
  • chat - ссылка на идентификатор чата, в который было отправлено сообщение
  • author - ссылка на идентификатор отправителя сообщения, отношение многие-к-одному
  • text - текст отправленного сообщения
  • created_at - время создания

Основные API методы

Методы обрабатывают HTTP POST запросы c телом, содержащим все необходимые параметры в JSON.

Добавить нового пользователя

Принимает в качестве полей: имя пользователя.

Ответ: id созданного пользователя или HTTP-код ошибки.

Создать новый чат между пользователями

Принимает в качестве полей: имя чата и массив id пользователей в чате.

Ответ: id созданного чата или HTTP-код ошибки.

Количество пользователей не ограничено.

Отправить сообщение в чат от лица пользователя

Принимает в качестве полей: id чата, id автора сообщения и текст сообщения.

Ответ: id созданного сообщения или HTTP-код ошибки.

Получить список чатов конкретного пользователя

Принимает в качестве полей: id пользователя.

Ответ: cписок всех чатов со всеми полями, отсортированный по времени создания последнего сообщения в чате (от позднего к раннему). Или HTTP-код ошибки.

Получить список сообщений в конкретном чате

Принимает в качестве полей: id чата.

Ответ: список всех сообщений чата со всеми полями, отсортированный по времени создания сообщения (от раннего к позднему). Или HTTP-код ошибки.

Реализация

  • Следование дизайну REST API.
  • Подход "Чистой Архитектуры" и техника внедрения зависимости.
  • Работа с фреймворком echo.
  • Работа с БД Postgres с использованием библиотеки sqlx и написанием SQL запросов.
  • Конфигурация приложения - библиотека viper.
  • Реализация Graceful Shutdown.
  • Запуск из Docker.
  • Юнит-тестирование бизнес-логики и взаимодействия с БД классическим способом и с помощью моков - библиотеки testify, mock.
  • Сквозное (E2E) тестирование - BDD фреймворк goconvey.
  • Проверка кода на соответствие стандартам с помощью линтера - утилита golangci-lint
  • Автоматическое создание документации с помощью Swagger 2.0 - библиотека echo-swagger.
  • Непрерывная интеграция - сборка приложения, проверка линтером и запуск тестов в Github action.

Структура проекта:

.
├── pkg
│   ├── error_message  // сообщения об ошибках
│   ├── model          // основные структуры
│   ├── delivery       // обработчики запросов
│   ├── service        // бизнес-логика
│   └── repository     // взаимодействие с БД
├── cmd                // точка входа в приложение
├── migrations         // SQL файлы с миграциями
├── tet_scripts        // SQL файлы с тестовыми данными
├── configs            // файлы конфигурации
├── test               // инициализация тестовой БД
└── e2e_test.go        // сквозной тест

Архитектура

Схема

Приложение имеет 3 основных слоя, реализованных в отдельных пакетах.

  • Repository - слой взаимодействия с БД. Методы этого слоя принимают данные от Service и выполняют запросы к БД.
  • Service - слой бизнес-логики. Методы этого слоя принимают данные от Handler и применяют к ним бизнес-правила для достижения цели варианта использования.
  • Delivery - слой обработчиков запросов. Содержит методы-обработчики для endpoints.

Пакет Model содержит структуры сущностей, используемых остальными слоями.

Запуск

make build
make run

Миграции накатываются автоматически при запуске приложения.

Тестирование

Локальный запуск тестов:

make run_test

Для локального запуска тестов необходимо создать тестовую БД. Это можно сделать следующей командой (необходима утилита psql):

make create_test_db

Документация

Для просмотра документации Swagger необходимо запустить приложение и перейти по ссылке http://127.0.0.1:9000/swagger/index.html

Нагрузочное тестирование

Нагрузочное тестирование проведено с помощью утилиты Apache Benchmark. Результаты представлены в файле ab_results.md

Примеры

Создание пользователя

Запрос:

$ curl --header "Content-Type: application/json" \
  --request POST \
  --data '{"username": "user_1"}' \
  http://localhost:9000/users/add

Тело ответа:

{
    "id":"74e6f204-4a47-40b9-aad1-8ea40887867f"
}
Создание чата

Запрос:

$ curl --header "Content-Type: application/json" \
  --request POST \
  --data '{"name": "chat_1", "users": ["2205ead6-79b6-45a0-93cf-9a1fdcb1f3d8", "74e6f204-4a47-40b9-aad1-8ea40887867f"]}' \
  http://localhost:9000/chats/add

Тело ответа:

{
    "id":"43e59947-0c56-44a3-b110-51a88f26fe75"
}
Создание сообщения

Запрос:

$ curl --header "Content-Type: application/json" \
  --request POST \
  --data '{"chat": "43e59947-0c56-44a3-b110-51a88f26fe75", "author": "2205ead6-79b6-45a0-93cf-9a1fdcb1f3d8", "text": "hi"}' \
  http://localhost:9000/messages/add

Тело ответа:

{
    "id":"27f79a71-b8fd-4f04-a140-d71530945c80"
}
Получение всех чатов пользователя

Запрос:

$ curl --header "Content-Type: application/json" \
  --request POST \
  --data '{"user": "2205ead6-79b6-45a0-93cf-9a1fdcb1f3d8"}' \
  http://localhost:9000/chats/get

Тело ответа:

[
    {
        "id": "43e59947-0c56-44a3-b110-51a88f26fe75",
        "name": "chat_1",
        "users": [
            "2205ead6-79b6-45a0-93cf-9a1fdcb1f3d8",
            "74e6f204-4a47-40b9-aad1-8ea40887867f"
        ],
        "created_at": 1624600288,
        "last_message_time": 1624600921
    },
    {
        "id": "8e1ae287-8b99-4e25-9598-db5e6fc77a99",
        "name": "Chat 1",
        "users": [
            "2205ead6-79b6-45a0-93cf-9a1fdcb1f3d8",
            "08a1fb77-4d05-4b8a-a9f9-f606c3680516"
        ],
        "created_at": 400,
        "last_message_time": 700
    },
    {
        "id": "239998e6-b6b2-406f-994b-20a55e165a88",
        "name": "Chat 2",
        "users": [
            "2205ead6-79b6-45a0-93cf-9a1fdcb1f3d8",
            "08a1fb77-4d05-4b8a-a9f9-f606c3680516",
            "ea4e8ba2-798f-4535-83e2-e7ae4e776136"
        ],
        "created_at": 500,
        "last_message_time": 650
    }
]
Получение всех сообщений в чате

Запрос:

$ curl --header "Content-Type: application/json" \
  --request POST \
  --data '{"chat": "43e59947-0c56-44a3-b110-51a88f26fe75"}' \
  http://localhost:9000/messages/get

Тело ответа:

[
    {
        "id": "27f79a71-b8fd-4f04-a140-d71530945c80",
        "chat_id": "43e59947-0c56-44a3-b110-51a88f26fe75",
        "author_id": "2205ead6-79b6-45a0-93cf-9a1fdcb1f3d8",
        "text": "hi",
        "created_at": 1624600921
    },
    {
        "id": "08dea60a-4e7d-4fcc-a209-748b423ee548",
        "chat_id": "43e59947-0c56-44a3-b110-51a88f26fe75",
        "author_id": "74e6f204-4a47-40b9-aad1-8ea40887867f",
        "text": "How have you been?",
        "created_at": 1624602090
    }
]

Directories

Path Synopsis
docs
internal
repository/mocks
Package mock_repository is a generated GoMock package.
Package mock_repository is a generated GoMock package.
service/mocks
Package mock_service is a generated GoMock package.
Package mock_service is a generated GoMock package.

Jump to

Keyboard shortcuts

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