Files
3ybactuk-marketplace-go-ser…/docs/homework-1
2025-05-31 10:47:47 +00:00
..
2025-05-17 15:06:08 +03:00
2025-05-17 15:06:08 +03:00

Домашнее задание по модулю "Основы Go"

Необходимо реализовать сервис для работы с корзиной пользователя Cart

Основное задание

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

Требования к решению:

  1. Используем HTTP, на основе стандартной библиотеки Go 1.23
  2. Для определения существования товара делаем поход в сервис product-service
  3. Состояние храним в in-memory, персистентное хранилище на данный момент не требуется
  4. Никакого резерва стоков не делаем, логика простейшая

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

  1. Делаем Middleware, который будет логировать поступающие запросы
  2. Делаем валидацию входящих структур на основе любой Open Source библиотеки (можно подсмотреть тут - https://awesome-go.com/validation/)
  3. Делаем ретраи в product-service на 420/429 статус в виде Client Middleware. 3 ретрая, потом ошибка

Спецификация

Добавить товар в корзину

Идентификатором товара является числовой идентификатор SKU. Метод добавляет указанный товар в корзину определенного пользователя. Каждый пользователь имеет числовой идентификатор userID. При добавлении в корзину проверяем, что товар существует в специальном сервисе.

Один и тот же товар может быть добавлен в корзину несколько раз, при этом количество экземпляров складывается.

Метод URI
POST /user/<user_id>/cart/<sku_id>

Параметры запроса:

Параметр Тип параметра Тип данных Пример Описание
user_id query path int64 1007 Идентификатор пользователя, в корзину которого добавляется товар
sku_id query path int64 2008 Идентификатор товара, добавляемого в корзину
count body uint32 12 Количество товаров, добавляемое в корзину

Параметры ответа:

отсутствуют

Параметры ошибочных ответов:

Сценарий HTTP код ошибки Описание
Добавление валидного SKU для пользователя (user_id) с нулевым или отрицательным значением 400 Идентификатор пользователя должен быть натуральным числом (больше нуля)
Добавление SKU с нулевым или отрицательным значением 400 SKU должен быть натуральным числом (больше нуля)
Добавление SKU с нулевым или отрицательным количеством (count) 400 Количество должно быть натуральным числом (больше нуля)
Добавление несуществующего SKU в корзину 412 SKU должен существовать в сервисе product-service

Диаграмма последовательности:

cart-cart-item-add

Удалить товар из корзины

Метод полностью удаляет все количество товара из корзины пользователя. Если у пользователя вовсе нет данной позиции, то возвращается такой же ответ, как будто бы все позиции данного sku были успешно удалены.

Метод URI
DELETE /user/<user_id>/cart/<sku_id>

Параметры запроса:

Параметр Тип параметра Тип данных Пример Описание
user_id query path int64 1007 Идентификатор пользователя, в корзину которого добавляется товар
sku_id query path int64 2008 Идентификатор товара, удаляемого из корзины

Параметры ответа:

отсутствуют

Параметры ошибочных ответов:

Сценарий HTTP код ошибки Описание
Удаление SKU с нулевым или отрицательным значением 400 SKU должен быть натуральным числом (больше нуля)
Удаление SKU с нулевым или отрицательным пользователем (user_id) 400 Идентификатор пользователя должен быть натуральным числом (больше нуля)

Диаграмма последовательности:

cart-cart-item-delete

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

Метод полностью очищает корзину пользователя. Если у пользователя нет корзины или она пуста, то, как и при успешной очистке корзины, необходимо вернуть код ответа 204 No Content.

Метод URI
DELETE /user/<user_id>/cart

Параметры запроса:

Параметр Тип параметра Тип данных Пример Описание
user_id query path int64 1007 Идентификатор пользователя, в корзину которого добавляется товар

Параметры ответа:

отсутствуют

Параметры ошибочных ответов:

Сценарий HTTP код ошибки Описание
Удаление корзины с нулевым или отрицательным пользователем (user_id) 400 Идентификатор пользователя должен быть натуральным числом (больше нуля)

Диаграмма последовательности:

cart-cart-clear

Получить содержимое корзины

Метод возвращает содержимое корзины пользователя на текущий момент. Если корзины у переданного пользователя нет, либо она пуста, следует вернуть 404 код ответа. Товары в корзине упорядочены в порядке возрастания sku.

Метод URI
GET /user/<user_id>/cart

Параметры запроса:

Параметр Тип параметра Тип данных Пример Описание
user_id query path int64 1007 Идентификатор пользователя, в корзину которого добавляется товар

Параметры ответа:

Параметр Тип данных Пример Описание
items[i].sku int64 2008 Идентификатор товара в корзине пользователя
items[i].name string "Гречка пропаренная, в пакетиках для варки, 400" Наименование товара
items[i].count uint32 10 Количество единиц товара
items[i].price uint32 16 Стоимость единицы товара в условных единицах
total_price uint32 160 Суммарная стоимость всех товаров в корзине

Пример ответа:

{
    "items" : [
        {
            "sku": 2958025,
            "name": "Roxy Music. Stranded. Remastered Edition",
            "count": 2,
            "price": 1028
        },
        {
            "sku": 773297411,
            "name": "Кроссовки Nike JORDAN",
            "count": 1,
            "price": 2202
        }
    ],
    "total_price": 4258
}

Параметры ошибочных ответов:

Сценарий HTTP код ошибки Описание
Запрос корзины с нулевым или отрицательным пользователем (user_id) 400 Идентификатор пользователя должен быть натуральным числом (больше нуля)

Диаграмма последовательности:

cart-cart-list

Взаимодействие с Product service

Если, вызвав make run-all, развернуть деплоймент, swagger этого сервиса
можно увидеть локально по адресу: http://localhost:8082/docs/

Сервис поддерживает следующие операции:

GET /product?count=10&start_after_sku=0

Эта операция имеет два необязательных параметра:

  • count — сколько элементов вернуть и
  • start_after_sku — после какого элемента начать вывод.

Response:

[
    {
        name  string
        price int32
        sku   int64 
    },
]

GET /product/<sku>

Эта операция выводит данные товара с заданным sku.

Response:

    {
        name  string
        price int32
        sku   int64 
    }

Обратите внимание, сервис product-service отдаёт цены в int32 формате.
В JSON нет беззнаковых целых, поэтому int32.
Вам же, внутри своих сервисов, для совместимости их между собой
следует использовать беззнаковый тип uint32.

Также следует обратить внимание на то, что он выведен на localhost:8082 лишь
для вашего удобства работы с данными.

Ваш сервис cart, запущенный докер-контейнером, сможет подключиться к product-service
по адресу product-service:8082 — заниматься маршрутизацией будет сам докер.

Авторизация на запрос выполняется с помощью заголовка X-API-KEY и токена testToken.

Makefile

В рамках данного задания необходимо имплементировать следующие таргеты:

  • run-all — запускает сервисы. На данный момент их должно стать два:
    • product-service — уже реализован
    • cart — разрабатываемый вами в качестве домашнего задания

Ожидаемый результат

  • с помощью команды make run-all можно запустить приложение
  • приложение слушает HTTP-запросы на порту 8080
  • реализованы API-методы
    • POST /user/<user_id>/cart/<sku_id>
    • DELETE /user/<user_id>/cart/<sku_id>
    • DELETE /user/<user_id>/cart
    • GET /user/<user_id>/cart
  • методы реализуют заявленную бизнес-логику
  • методы валидируют запросы и отдают описанные в спецификации коды ошибок
  • информация о пользователях и их состоянии корзины хранится в памяти приложения
  • при рестарте приложения состояние системы теряется

Автоматические проверки

Ваше решение должно проходить автоматические проверки:

  • Компиляция
  • Линтер
  • Unit-тесты (если есть)
  • Автотесты

Прохождение автоматических проверок влияет на итоговую оценку за домашнюю работу.

Сценарии тестирования с примерами запроса (для тьютора)

Сценарий тестирования следует описать в cart.http

Дедлайны сдачи и проверки задания:

  • 24 мая 23:59 (сдача) / 27 мая, 23:59 (проверка)