Skip to content
/ tasks Public

Exercise for developing the Tasks application

Notifications You must be signed in to change notification settings

yanusa3/tasks

Repository files navigation

Task Service

Микросервис для управления задачами (tasks) с использованием FastAPI, SQLAlchemy и Redis.

Описание проекта

Этот проект представляет собой RESTful API для управления задачами. Основные возможности:

  • Создание задач.
  • Получение списка задач с поддержкой кэширования.
  • Обновление статуса задачи (перевод из статуса "pending" в статус "completed").

Структура каталогов

Этот документ описывает структуру каталогов проекта и назначение каждого файла и директории.


Корневая директория

  • Dockerfile: Файл для сборки Docker-образа приложения.
  • README.md: Основная документация проекта с описанием, инструкциями по запуску и использованием.
  • ROADMAP.md: Дорожная карта проекта с перечнем задач и планов на будущее.
  • docker-compose.yml: Конфигурация Docker Compose для запуска приложения, PostgreSQL и Redis.
  • example.env: Пример файла .env с переменными окружения. Используется как шаблон для настройки окружения.
  • pytest.ini: Конфигурационный файл для настройки тестов с использованием pytest.
  • requirements.txt: Список зависимостей Python, необходимых для работы приложения.

Директория app

Основная директория с исходным кодом приложения.


Директория db_dumps

Директория для хранения дампов базы данных.

  • dump_10000.sql: Дамп базы данных с 10,000 записями.
  • dump_1000000.sql: Дамп базы данных с 1,000,000 записями.

Директория scripts

Директория для хранения полезных скриптов.

  • generate_tasks.sh: Скрипт для генерации тестовых задач с использованием curl.

Примечание

  1. Настройка окружения:

    • Скопируйте example.env в .env и заполните переменные окружения.
  2. Генерация тестовых данных:

    • Запустите скрипт sh scripts/generate_tasks.sh для создания тестовых задач.

Технологии

  • Python: Высокоуровневый язык программирования общего назначения.
  • FastAPI: Веб-фреймворк для создания API.
  • SQLAlchemy: ORM для работы с базой данных.
  • PostgreSQL: Реляционная база данных для хранения задач.
  • Redis: Кэширование данных для повышения производительности.
  • Uvicorn: ASGI-сервер для запуска FastAPI.
  • Docker-compose: Инструмент для управления многоконтейнерными приложениями в Docker.
  • Docker: Платформа для разработки, доставки и запуска приложений в изолированных средах

Архитектура приложения

Приложение построено по принципу многослойной архитектуры (Layered Architecture), что обеспечивает четкое разделение ответственности между компонентами. Основные слои:

1. Слой представления (Presentation Layer)

  • FastAPI: Используется для создания RESTful API. FastAPI обеспечивает высокую производительность за счет асинхронной обработки запросов.
  • Эндпоинты: Определяют маршруты API (например, /tasks) и обрабатывают HTTP-запросы.
  • Pydantic: Используется для валидации входных данных и сериализации ответов.

2. Слой бизнес-логики (Business Logic Layer)

  • CRUD-операции: Логика создания, чтения, обновления и удаления задач реализована в модуле crud.
  • Валидация статусов: Проверка, что задача не может быть переведена из статуса "завершено" в другой статус.
  • Кэширование: Логика работы с кэшем (Redis) для повышения производительности.

3. Слой доступа к данным (Data Access Layer)

  • SQLAlchemy: ORM для работы с базой данных. Позволяет абстрагироваться от конкретной СУБД.
  • Модели данных: Определены в модуле DataBaseModel. Например, модель BaseTask описывает структуру задачи.
  • Асинхронные запросы: Используются для взаимодействия с базой данных, чтобы не блокировать основной поток выполнения.

4. Слой кэширования (Caching Layer)

  • Redis: Используется для хранения кэшированных данных. Кэш обновляется при изменении данных в базе.
  • Блокировки: Для предотвращения race conditions при обновлении кэша используются асинхронные блокировки (AsyncRedisLock). Это особенно важно, когда несколько запросов одновременно пытаются обновить кэш.
    • Как это работает:
      1. При первом запросе, если данные отсутствуют в кэше, захватывается блокировка.
      2. Другие запросы, пришедшие в это же время, ожидают освобождения блокировки.
      3. Если блокировка не освобождается в течение заданного таймаута (настраивается в settings.CACHE_LOCK_TIMEOUT), запрос завершается с ошибкой 429 Too Many Requests, чтобы предотвратить долгое ожидание.
      4. После обновления кэша блокировка освобождается, и следующие запросы используют обновленные данные.
    • Преимущества:
      • Исключается ситуация, когда несколько процессов одновременно обновляют кэш.
      • Повышается согласованность данных.
      • Таймаут предотвращает бесконечное ожидание и обеспечивает отказоустойчивость.

5. Слой инфраструктуры (Infrastructure Layer)

  • Настройки: Конфигурация приложения (например: включение/выключение кэширования) управляется через модуль settings.
  • Логирование: Используется модуль logger для записи логов выполнения операций.
  • Обработка ошибок: Централизованная обработка ошибок (например, ошибки подключения к Redis или базе данных).

Взаимодействие компонентов

  1. Запрос поступает в FastAPI:

    • Эндпоинт обрабатывает HTTP-запрос (например, GET /tasks).
    • Данные валидируются с помощью Pydantic.
  2. Обращение к бизнес-логике:

    • Если кэширование включено, данные сначала запрашиваются из Redis.
    • Если данных в кэше нет, выполняется запрос к базе данных через SQLAlchemy.
  3. Работа с базой данных:

    • SQLAlchemy выполняет запросы к базе данных (например, SELECT * FROM tasks).
    • Данные возвращаются в виде объектов Python.
  4. Кэширование:

    • Если данные были получены из базы, они сохраняются в Redis для последующих запросов.
    • При изменении данных (например, создании новой задачи) кэш инвалидируется.
  5. Формирование ответа:

    • Данные сериализуются в JSON с помощью Pydantic.
    • Ответ возвращается клиенту.

Обоснование выбора технологий

Сравнительный анализ Nest.js и FastAPI показал, что обе технологии обладают схожими возможностями. Однако Nest.js чаще используется для приложений, где требуется интеграция с пользовательским интерфейсом (UI). В нашем случае проект представляет собой сервис без пользовательского интерфейса.


Почему FastAPI?

  1. Простота и скорость разработки:

    • FastAPI предоставляет удобный и интуитивно понятный синтаксис, что ускоряет разработку.
    • Встроенная поддержка асинхронности позволяет эффективно обрабатывать запросы.
  2. Отсутствие необходимости в UI:

    • FastAPI идеально подходит для создания API-сервисов, где не требуется пользовательский интерфейс.
  3. Производительность:

    • FastAPI основан на Starlette и Pydantic, что обеспечивает высокую производительность и минимальные задержки.
  4. Документация и сообщество:

    • FastAPI автоматически генерирует документацию (Swagger и ReDoc), что упрощает взаимодействие с API.
    • Активное сообщество и множество готовых решений для типичных задач.

Почему не Nest.js?

  1. Ориентация на UI:

    • Nest.js чаще используется в проектах, где требуется интеграция с фронтендом (например, Angular или React).
  2. Сложность для простых API:

    • Для сервисов без UI использование Nest.js может быть избыточным, так как он требует больше настроек и boilerplate-кода.
  3. Производительность:

    • Хотя Nest.js также поддерживает асинхронность, FastAPI показывает лучшую производительность в тестах.

Итог

Выбор FastAPI обусловлен его простотой, производительностью и ориентированностью на создание API-сервисов без необходимости интеграции с пользовательским интерфейсом. Это делает его идеальным решением для нашего проекта.


Инструкция по запуску приложения

Это руководство поможет вам запустить приложение с использованием Docker и Docker Compose.

1. Подготовка окружения

Установите Docker и Docker Compose

Убедитесь, что у вас установлены Docker и Docker Compose. Проверьте их версии:

docker --version
docker-compose --version

Конфигурация окружения (.env):

Для корректной работы приложения необходимо настроить переменные окружения в файле .env. Этот файл необходимо создать в корне проекта.

Пример конфигурации example.env:

# Настройки приложения
APP_PORT=8080
CACHE_TIMEOUT=300
CACHE_TURNED_ON=true

# Настройки PostgreSQL
POSTGRES_USER=user
POSTGRES_PASSWORD=password
POSTGRES_DB=tasks_db
POSTGRES_HOST=postgres
POSTGRES_PORT=5432

# Настройки Redis
REDIS_HOST=redis
REDIS_PORT=6379

Описание переменных окружения

Настройки приложения

  • APP_PORT: Порт, на котором будет доступно приложение.
  • CACHE_TIMEOUT: Время (в секундах), в течение которого данные хранятся в кэше.
  • CACHE_TURNED_ON: Включение или выключение кэширования. Возможные значения: true (включено) или false (выключено).

Настройки PostgreSQL

  • POSTGRES_USER: Имя пользователя для подключения к базе данных PostgreSQL.
  • POSTGRES_PASSWORD: Пароль для подключения к базе данных PostgreSQL.
  • POSTGRES_DB: Название базы данных PostgreSQL.
  • POSTGRES_HOST: Хост для подключения к PostgreSQL (обычно postgres при использовании Docker).
  • POSTGRES_PORT: Порт для подключения к PostgreSQL (по умолчанию 5432).

Настройки Redis

  • REDIS_HOST: Хост для подключения к Redis (обычно redis при использовании Docker).
  • REDIS_PORT: Порт для подключения к Redis (по умолчанию 6379).

Примечания

  • Корректность заполнения переменных: Убедитесь, что все переменные окружения заполнены корректно. В противном случае приложение может не запуститься или работать некорректно.

  • Использование с Docker: Если вы используете Docker, переменные окружения будут автоматически подхвачены из файла .env. Убедитесь, что файл .env находится в корневой директории проекта.

  • Безопасность: Не передавайте файл .env с чувствительными данными (например, паролями) в публичные репозитории. Используйте .gitignore, чтобы исключить его из коммитов.

2. Сборка и запуск приложения

Соберите и запустите контейнеры

  1. Перейдите в корневую директорию проекта.
  2. Выполните следующую команду:
docker-compose up --build

Проверка работы приложения:

После успешного запуска приложение будет доступно по адресу: http://localhost:8080

Вы можете проверить доступность API, например, с помощью команды curl:

curl http://localhost:8080/tasks

3. Остановка и удаление контейнеров

Остановка контейнеров:

Чтобы остановить контейнеры, выполните:

docker-compose down

Удаление контейнеров и томов:

Если вы хотите удалить контейнеры и тома (включая данные PostgreSQL и Redis), выполните:

docker-compose down -v

4. Дополнительные команды

Просмотр логов:

Чтобы просмотреть логи конкретного сервиса (например, app), выполните:

docker-compose logs app

Подключение к базе данных:

Вы можете подключиться к PostgreSQL с помощью команды:

docker exec -it tasks_postgres_db psql -U postgres -d tasks_db

Подключение к Redis:

Вы можете подключиться к Redis с помощью команды:

docker exec -it tasks_redis_cache redis-cli

About

Exercise for developing the Tasks application

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published