В нашей компании есть много различных микросервисов. Многие из них так или иначе хотят взаимодействовать с балансом пользователя. На архитектурном комитете приняли решение централизовать работу с балансом пользователя в отдельный сервис.
Необходимо реализовать микросервис для работы с балансом пользователей (зачисление средств, списание средств, перевод средств от пользователя к пользователю, а также метод получения баланса пользователя). Сервис должен предоставлять HTTP API и принимать/отдавать запросы/ответы в формате JSON.
- Реализовать метод получения списка транзакций с комментариями откуда и зачем были начислены/списаны средства с баланса. Необходимо предусмотреть пагинацию и сортировку по сумме и дате.
- Добавить к методу получения баланса доп. параметр. Пример: ?currency=USD. Если этот параметр присутствует, то мы должны конвертировать баланс пользователя с рубля на указанную валюту. Данные по текущему курсу валют можно взять отсюда https://exchangeratesapi.io/ или из любого другого открытого источника.
- Сервис разработан на языке Golang с использованием чистой архитектуры
- В качестве базы данных используется PostgresSQL
- Для всех слоев:
delivery
,usecase
,repository
написаны тесты. Для слояrepository
использовался pgxmock, для слоевdelivery
иusecase
использовались моки интерфейсов, моки сгенерированы с помощью gomock - API сервиса задокументировано с использованием Swagger
- Реализован docker-compose состоящий из двух контейнеров: приложение и база данных
- Для удобства взаимодействия с проектом реализован
Makefile
- Настроен CI: линтер и тесты
В сервисе реализованы оба дополнительных задания. Для получения актуального курса валют выполняется GET запрос к публичному API ЦБ РФ. Согласно документации API, при его бесплатном использовании, данные обновляются раз в сутки. В следствие чего в сервисе реализована отдельная горутина, которая раз в сутки выполняет GET запрос для получения актуального курса валют. Для избежания утечки горутин функция принимает канал отмены, таким образом, при завершении работы сервиса, горутина успешно завершит свою работу. Актуальный курс валют сохраняется в хэш-карту, все операции чтения и записи происходят с использованием sync.RWMutex
- являются потокобезопасными.
Запуск сервиса c использованием Docker
make run
Запуск тестов
make run-tests
Запуск линтера
make lint
GET /api/v1/balance/{user_id}?currency={currency}
Параметры запроса:
- user_id - id пользователя в сервисе
- currency - опциональный параметр - валюта, в которой необходимо получить балланс, по умолчанию - российский рубль
Ответ:
200-ОК
{
"user_id": 1,
"balance": 2500
}
Коды ответа:
- 200 - ОК
- 400 - некорректные параметры запроса
- 404 - пользователь не найден
- 422 - неподдерживаемая валюта для перевода
- 500 - внутренняя ошибка сервера
POST /api/v1/balance/{user_id}
Параметры запроса:
- user_id - id пользователя в сервисе
Тело запроса:
{
"operation_type": 1,
"amount": 2500
}
- operation_type - тип операции (1 - пополнение балланса, 2 - списание денег с балланса)
- amount - сумма списания/пополнения
Ответ:
200-ОК
{
"user_id": 1,
"balance": 2500
}
Коды ответа:
- 200 - ОК
- 400 - некорректные параметры или тело запроса
- 422 - недостаточно средств для совершения операции, неподдерживаемый тип операции, некорректный ID пользователя, не задана сумма списания/пополнения
- 500 - внутренняя ошибка сервера
POST /api/v1/transfer
Тело запроса:
{
"sender_id": 1,
"receiver_id": 2,
"amount": 2500
}
- sender_id - ID отправителя
- receiver_id - ID получателя
- amount - сумма денег для перевода
Ответ:
200-ОК
{
"sender": {
"user_id": 1,
"balance": 3500
},
"receiver": {
"user_id": 2,
"balance": 5500
}
}
Коды ответа:
- 200 - ОК
- 400 - некорректное тело запроса
- 404 - отправитель или получатель не найдены
- 422 - недостаточно денег для совершения перевода
- 500 - внутренняя ошибка сервера
POST /api/v1/transactions/{user_id}
Параметры запроса:
- user_id - id пользователя в сервисе
Тело запроса:
{
"limit": 10,
"operation_type": "add",
"since": "2022-01-18T21:27:20.969985Z",
"order_amount": true,
"order_date": true
}
- limit - ограничение количества транзакций для вывода
- operation_type - тип операции для выборки - пополнение/снятие/перевод
- since - ограничение по дате и времени - начиная с какой даты будут получены транзакции
- order_amount - сортировать транзакции по сумме
- order_date - сортировать транзакции по дате
Ответ:
200-ОК
[
{
"operation_type": "add",
"amount": 100000,
"created": "2022-01-18T21:27:20.969985Z"
},
{
"operation_type": "add",
"amount": 100000,
"created": "2022-01-18T21:27:21.432568Z"
},
]
Коды ответа:
- 200 - ОК
- 400 - некорректные параметры или тело запроса
- 404 - пользователь не найден
- 422 - некорретное значение поля limit в теле запроса
- 500 - внутренняя ошибка сервера