Skip to content

shestoi/subscription-service

Repository files navigation

subscription-service

REST API сервис для агрегации пользовательских онлайн-подписок.

Стек

  • Go
  • chi
  • PostgreSQL
  • pgx
  • slog
  • cleanenv
  • golang-migrate
  • swaggo
  • Docker Compose

Запуск локально

  1. Скопируйте пример переменных окружения:
cp .env.example .env
  1. Убедитесь, что PostgreSQL доступен на localhost:5432.

  2. Запустите сервис:

make run

Для локального запуска DATABASE_URL должен указывать на localhost.

Запуск через Docker Compose

make docker-up

Для Docker Compose DATABASE_URL использует host postgres (имя сервиса в сети compose) и задан прямо в docker-compose.yml.

Остановка:

make docker-down

Остановка с удалением volume:

make docker-down-v

Переменные окружения

APP_ENV=local
HTTP_ADDR=localhost:8080
DATABASE_URL=postgres://postgres:postgres@localhost:5432/subscriptions?sslmode=disable
SHUTDOWN_TIMEOUT=10s

Полезные команды Makefile

make run
make docker-up
make docker-down
make migrate-up
make migrate-down
make swagger
make fmt
make tidy

Миграции

Миграции лежат в директории migrations/ и применяются через golang-migrate.

Первая миграция создает таблицу subscriptions с индексами и базовыми ограничениями:

  • price >= 0
  • end_date >= start_date (если end_date задан)

Применить миграции:

make migrate-up

Откатить последнюю миграцию:

make migrate-down

Swagger

Установка CLI:

go install github.com/swaggo/swag/cmd/swag@latest

Генерация документации:

swag init -g ./cmd/app/main.go -o ./docs

Swagger UI:

http://localhost:8080/swagger/index.html

CI

Используется GitHub Actions.

Проверяется:

  • build (go build ./...)
  • tests (go test ./...)
  • formatting (test -z "$(gofmt -l .)")

Доступные endpoints

  • GET /health
  • POST /subscriptions
  • GET /subscriptions
  • GET /subscriptions/total
  • GET /subscriptions/{id}
  • PUT /subscriptions/{id}
  • DELETE /subscriptions/{id}
  • GET /swagger/index.html

Пример ответа для health:

{
  "status": "ok"
}

Поведение end_date

  • end_date опционален при создании подписки.
  • Если end_date не указан, подписка считается активной (без даты окончания).
  • При update:
    • чтобы изменить дату окончания, передайте "end_date": "MM-YYYY";
    • если end_date не передан, текущее значение не изменяется;
    • очистка end_date через null сейчас не поддерживается, так как это не требуется по ТЗ.

Ручная проверка API

Поднять Docker Compose:

make docker-up

Применить миграции:

make migrate-up

Health:

curl http://localhost:8080/health

Create subscription:

curl -X POST http://localhost:8080/subscriptions \
  -H "Content-Type: application/json" \
  -d '{
    "service_name": "Yandex Plus",
    "price": 400,
    "user_id": "60601fee-2bf1-4721-ae6f-7636e79a0cba",
    "start_date": "07-2025"
  }'

List subscriptions:

curl http://localhost:8080/subscriptions

List with filters:

curl "http://localhost:8080/subscriptions?user_id=60601fee-2bf1-4721-ae6f-7636e79a0cba&service_name=Yandex%20Plus&limit=20&offset=0"

Get by id:

curl http://localhost:8080/subscriptions/<subscription-id>

Update:

curl -X PUT http://localhost:8080/subscriptions/<subscription-id> \
  -H "Content-Type: application/json" \
  -d '{
    "price": 500,
    "end_date": "12-2025"
  }'

Delete:

curl -X DELETE http://localhost:8080/subscriptions/<subscription-id>

Total cost:

curl "http://localhost:8080/subscriptions/total?from=07-2025&to=12-2025&user_id=60601fee-2bf1-4721-ae6f-7636e79a0cba&service_name=Yandex%20Plus"

Пояснение для GET /subscriptions/total:

  • from и to обязательны и передаются в формате MM-YYYY;
  • период считается включительно по месяцам;
  • end_date = NULL означает активную подписку без даты окончания.

About

Backend REST API сервис для управления и агрегации пользовательских подписок. Реализован на Go с PostgreSQL, Swagger, Docker Compose и GitHub Actions CI.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors