https://github.com/tmrrwnxtsn/const-payments-api
:money_with_wings: RESTful API эмулятора платёжного сервиса
https://github.com/tmrrwnxtsn/const-payments-api
docker-compose go golang migrations postgresql restful-api swagger-codegen
Last synced: 4 months ago
JSON representation
:money_with_wings: RESTful API эмулятора платёжного сервиса
- Host: GitHub
- URL: https://github.com/tmrrwnxtsn/const-payments-api
- Owner: tmrrwnxtsn
- License: mit
- Created: 2022-06-03T15:52:28.000Z (almost 4 years ago)
- Default Branch: master
- Last Pushed: 2022-06-22T20:54:50.000Z (almost 4 years ago)
- Last Synced: 2024-11-15T00:51:37.333Z (over 1 year ago)
- Topics: docker-compose, go, golang, migrations, postgresql, restful-api, swagger-codegen
- Language: Go
- Homepage:
- Size: 4.38 MB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Эмулятор платёжного сервиса
[](https://goreportcard.com/report/github.com/tmrrwnxtsn/const-payments-api)
[](https://codebeat.co/projects/github-com-tmrrwnxtsn-const-payments-api-master)
[](https://pkg.go.dev/github.com/tmrrwnxtsn/const-payments-api)
Тестовое задание на стажировку в [Константу](https://const.tech/).
## Содержание
- [Задание](#Задание)
- [Подготовка](#Подготовка)
- [Запуск](#Запуск)
- [Эндпойнты](#Эндпойнты)
- [Тесты](#Тесты)
- [Структура](#Структура)
- [Зависимости](#Зависимости)
## Задание
Сервис должен принимать запросы через REST API, сохранять/изменять состояния платежей в базе данных. Код должен быть
написан на Go. В качестве базы данных, пожалуйста, используй любую реляционную.
Мы будем работать с двумя сущностями: пользователь и транзакция. Для простоты допустим, что база пользователей хранится
вне нашего сервиса. О пользователе мы можем знать только его ID (число) и email. Транзакции хранятся в нашем сервисе.
Вот что нам надо хранить о каждой транзакции
- ID транзакции (число)
- ID пользователя
- email пользователя
- сумма
- валюта
- дата и время создания
- дата и время последнего изменения
- статус
Статус может принимать одно из следующих значений: НОВЫЙ, УСПЕХ, НЕУСПЕХ, ОШИБКА. Цикл жизни платежа выглядит следующим
образом: пользователь создает платеж, он создается в статусе НОВЫЙ. После платежная система должна уведомить нас о том,
прошел ли платеж на ее стороне (п. 2 ниже), после чего мы меняем статус в нашей базе. Статусы УСПЕХ и НЕУСПЕХ являются
терминальными - если платеж находится в них, его статус должно быть невозможно поменять. Переход в статусы УСПЕХ и
НЕУСПЕХ должен осуществляться только после получения запроса из п.2 ОШИБКА - это статус, когда в момент создания платежа
что-то пошло не так. Будет хорошо, если сделаешь, чтобы случайное количество платежей при создании переходили в этот
статус.
API должно поддерживать следующие действия:
- Создание платежа (на вход принимает id пользователя, email пользователя, сумму и валюту платежа);
- Изменение статуса платежа платежной системой (хорошо, если будет к этому запросу будет применяться авторизация);
- Проверка статуса платежа по ID;
- Получение списка всех платежей пользователя по его ID;
- Получение списка всех платежей пользователя по его e-mail;
- Отмена платежа по его ID. API должно вернуть ошибку, если отмена невозможна (например потому что платеж в том статусе,
в котором отменить нельзя).
## Подготовка
Сервис состоит из двух компонентов: API сервер и база данных PostgreSQL, поэтому для его успешной работы необходимо
установить следующее ПО:
- [Go](https://golang.org/doc/install) >=1.17;
- [PostgreSQL](https://www.postgresql.org/docs/current/tutorial-start.html) >=13 при запуске API сервера с
использованием собственного сервера БД или [Docker](https://www.docker.com/get-started) >=20.10.14, если собственный
сервер БД отсутствует.
## Запуск
После установки необходимого ПО необходимо скачать исходный код сервиса и перейти в директорию с исходным кодом:
```shell
git clone https://github.com/tmrrwnxtsn/const-payments-api.git
cd const-payments-api
```
Есть несколько вариантов запуска системы, все из которых происходят
благодаря [Makefile](https://github.com/tmrrwnxtsn/const-payments-api/blob/master/Makefile). **Перед запуском
рекомендуется обратить внимание на переменные, указанные в этом файле, и изменить их, если потребуется**. Также следует
обратить внимание на конфигурационный
файл [configs/local.yml](https://github.com/tmrrwnxtsn/const-payments-api/blob/master/configs/local.yml) и внести
необходимые правки. Если возникнет необходимость задать соответствующие переменные среды окружения, то они должны
добавляться с префиксом *APP_*, например, *APP_BIND_ADDR* (
см. [docker-compose.yml](https://github.com/tmrrwnxtsn/const-payments-api/blob/master/docker-compose.yml)).
### 1. [Docker Compose](https://docs.docker.com/compose/gettingstarted/)
Пожалуй, самый "безболезненный" и простой способ. Оба компонента системы (API сервер и БД) разворачиваются в отдельных
Docker-контейнерах. Настройки компонентов указываются в
[docker-compose.yml](https://github.com/tmrrwnxtsn/const-payments-api/blob/master/docker-compose.yml).
```shell
# запуск компонентов в отдельных Docker-контейнерах (без тестовых данных)
make compose-up
```
### 2. Docker
Имеется возможность разворачивать в Docker-контейнерах как API сервер, так и БД.
```shell
# запуск БД в Docker-контейнере
make db-start
# применение миграций к БД
make migrate-up-docker
# загрузка тестовых данных в БД
make testdata-docker
# сборка образа API сервера
make build-docker
# запуск API сервера в Docker-контейнере на основе собранного образа
make run-docker
```
### 3. Local
Также есть возможность запустить API сервер локально (у себя на хосте), используя различные подключения к БД (
локальная/внешняя/Docker).
```shell
# применение миграций к БД
make migrate-up
# загрузка тестовых данных в БД
make testdata
# компиляция и запуск бинарника с API сервером на хосте
make run
# компиляция
make build
# запуск бинарника API сервера
make run
```
*Рекомендуется проверить настройки сервиса в соответствующих конфигурационных файлах перед запуском любым из
вышеописанных способов.*
## Эндпойнты
После успешного запуска сервиса одним из представленных способов, RESTful API сервер будет доступен по
адресу `http://localhost:8080` (если были использованы настройки по умолчанию, указанные
в [configs/local.yml](https://github.com/tmrrwnxtsn/const-payments-api/blob/master/configs/local.yml)). Сервер
поддерживает следующие эндпойнты:
* `POST /api/transactions/`: создание платежа (транзакции)
* `GET /api/transactions/`: получение списка всех платежей (транзакций) пользователя по его ID или e-mail.
* `GET /api/transactions/:id/status/`: проверка статуса платежа (транзакции) по ID
* `PATCH /api/transactions/:id/status/`: изменение статуса платежа (транзакции) системой
* `DELETE /api/transactions/:id`: отмена платежа (транзакции) по ID
* `GET /swagger/index.html`: Swagger-документация
## Тесты
Перед запуском тестов на хосте необходимо создать тестовую БД, применить к ней миграции и указать соответствующий URL
в [internal/store/sqlstore/store_test.go](https://github.com/tmrrwnxtsn/const-payments-api/blob/master/internal/store/sqlstore/store_test.go)
, либо задать в переменных среды (*APP_DSN_TEST*):
```go
// internal/store/sqlstore/store_test.go
package sqlstore_test
import (
"github.com/tmrrwnxtsn/const-payments-api/internal/config"
"os"
"testing"
)
var dsn string
func TestMain(m *testing.M) {
dsn = os.Getenv(config.EnvVariablesPrefix + "DSN_TEST")
if dsn == "" {
dsn = "postgres://127.0.0.1/const_payments_db_test?sslmode=disable&user=postgres&password=qwerty"
}
os.Exit(m.Run())
}
```
После этого можно переходить к запуску тестов:
```shell
# выполнение тестов сервиса (с информацией о покрытии в %)
make test
# получить детальную информацию о покрытии участков кода тестами (cover.out, cover.html)
make test-cover
```
## Структура
Ниже представлена структура сервиса (по папкам) с кратким описанием.
```
├── cmd основные приложения проекта
│ └── server приложение API сервера
├── configs конфигурационные файлы для различных сред развёртывания
├── docs сгенерированная Swagger-документация
├── internal внутренний код приложения
│ ├── config работа с конфигурационными данными
│ ├── handler маршрутизация HTTP-запросов
│ ├── model модели/сущности приложения
│ ├── server HTTP-сервер, используемый для обработки запросов
│ ├── service слой бизнес-логики для работы с платежами (транзакциями)
│ │ └── mocks моки бизнес-логики работы с платежами (транзакциями)
│ └── store слой хранения данных
│ ├── sqlstore хранилище данных
│ └── teststore тестовое хранилище данных (проверка логики хранения данных)
├── migrations миграции базы данных
├── scripts скрипты для операций над сервисом
└── testdata тестовые данные для БД
```
Компоновка пакетов в данном проекте осуществлялась в соответствии с популярным макетом организации Go-проектов
– [Standard Go Project Layout](https://github.com/golang-standards/project-layout/blob/master/README_ru.md).
## Зависимости
* Маршрутизация: [gin](https://github.com/gin-gonic/gin)
* Доступ к базе данных: [sqlx](https://github.com/jmoiron/sqlx)
* Драйвер PostgreSQL: [pgx](https://github.com/jackc/pgx)
* Миграции базы данных: [golang-migrate](https://github.com/golang-migrate/migrate)
* Валидация данных: [ozzo-validation](https://github.com/go-ozzo/ozzo-validation)
* Логгирование: [logrus](https://github.com/sirupsen/logrus)
* Генерация Swagger-документации: [swag](https://github.com/swaggo/swag)
* Генерация моков: [golang/mock](https://github.com/golang/mock)