24 окт. 2020 г.
Всем привет! Сегодня хотел бы поделиться опытом создания простейшего сервиса денежных транзакций. Сразу скажу, что сервис не предназначен для использования в production. Похожий сервис я реализовывал в качестве тестового задания. Само задание выглядело так:
Также явно не указано, но подразумевалось наличие тестов. Предположительно задание можно было сделать за 3-4 часа. Но, в результате, работа заняла около 8 часов.
Проект разработан на Symfony 5.1 c использованием Doctrine, FOSRestBundle и PHPUnit.
Создал 3 сущности: Wallet, Transaction, User. Транзакция производится между source и destination кошельками. Кошелек привязан к пользователю. Пользователь может иметь несколько кошельков. Валюта указывается для кошелька и транзакции. Валюта должна совпадать. Схема базы данных выглядит так:
https://dbdiagram.io/d/5f45434e7b2e2f40e9deb90a
Значения валют и комиссий положил в Enum.
REST API сделал с помощью FOSRestBundle. Для обработки запроса используется TransactionRequest. Создание транзакций обрабатывается в TransactionController и затем передается в сервис TransactionCreator. Для красивого отображения ошибок используется ValidationErrorResponse и ExceptionListener.
Авторизация пользователей сделана по логину паролю. Была идея использовать bearer token, но решил, что для данного примера это избыточно. Для авторизации используется механизм EventSubscriber
Данные для демонстрации создаются с помощью консольной команды. Вероятно, лучше было использовать фикстуру, но это требовало некоторых дополнительных действий. В итоге, решил использовать консольную команду.
Реализовал тесты на создание транзакций.
Позитивные сценарии:
Негативные сценарии:
Подготовил Docker сборку на основании этого руководства. Docker compose включает в себя nginx, php-fpm и mysql контейнеры.
Проект запускается в Docker. Необходимо клонировать репозиторий, запустить docker-compose, затем загрузить sample data.
git clone https://github.com/antonshell/money-transactions-service.git
cd money-transactions-service
docker-compose up
docker-compose exec php-fpm php bin/console sample-data:load
1 . Для проверки работы сервиса можно выполнить такой запрос:
curl --request GET \
--url http://127.0.0.1:18680/
2 . Создание транзакции от пользователя #1 для пользователя #2:
curl --request POST \
--url http://127.0.0.1:18680/transaction \
--header 'content-type: application/json' \
--header 'password: user1' \
--header 'username: user1@test.com' \
--data '{
"source": 1,
"destination": 3,
"amount": 1
}'
3 . От пользователя #2 для пользователя #1:
curl --request POST \
--url http://127.0.0.1:18680/transaction \
--header 'content-type: application/json' \
--header 'password: user2' \
--header 'username: user2@test.com' \
--data '{
"source": 3,
"destination": 1,
"amount": 1
}'
4 . Получение списка пользователей и кошельков. В реальном проекте этот метод должен быть доступен только администратору.
curl --request GET \
--url http://127.0.0.1:18680/dashboard
Пример доступен на github. На этом пока все. Спасибо за внимание!