lab4

0

Описание

Языки

  • Python99,2%
  • Dockerfile0,8%
README.md

REST API для библиотеки

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

Это REST API для управления библиотекой, реализованное на Python с использованием FastAPI. Проект демонстрирует принципы проектирования REST API: простота, стабильность, версионность, идемпотентность, ограничение частоты запросов и документация.

Лабораторные работы

  • Лабораторная работа №1: REST API на FastAPI (текущая версия)
  • Лабораторная работа №4: API на основе RabbitMQ (асинхронный обмен сообщениями)

Быстрый старт для Lab4

Для запуска проекта с RabbitMQ см. QUICKSTART.md.

Краткая инструкция:

Веб-интерфейсы:

Отчёт по Lab4: см. lab4/REPORT.md

Предметная область

Библиотека - система для управления книгами и авторами.

Сущности:

  1. Авторы (Authors)

    • ID (уникальный идентификатор)
    • Имя
    • Год рождения
  2. Книги (Books)

    • ID (уникальный идентификатор)
    • Название
    • Автор (связь с сущностью Author)
    • ISBN
    • Год издания
    • Статус (доступна, взята на руки, зарезервирована)
    • В v2 добавлены: описание, количество страниц, рейтинг
  3. Пользователи (Users)

    • ID
    • Имя пользователя
    • Хешированный пароль

Технологии

  • Python 3.8+
  • FastAPI - современный веб-фреймворк для создания API
  • Uvicorn - ASGI сервер для запуска приложения
  • Pydantic - валидация данных
  • JWT - аутентификация через JSON Web Tokens
  • bcrypt - хеширование паролей
  • slowapi - rate limiting

Установка и запуск

1. Установка зависимостей

2. Запуск сервера

Примечание: Если команда

uvicorn
не найдена, используйте
python -m uvicorn
вместо просто
uvicorn
.

Сервер запустится на

http://localhost:8000

3. Доступ к документации

После запуска доступна автоматическая документация:

Структура проекта

. ├── main.py # Главный файл приложения ├── requirements.txt # Зависимости проекта ├── README.md # Этот файл └── app/ ├── __init__.py ├── models.py # Модели данных (Pydantic схемы) ├── database.py # Внутреннее хранилище данных ├── auth.py # Модуль аутентификации (JWT) ├── middleware/ │ └── rate_limit.py # Middleware для rate limiting └── routers/ ├── auth.py # Endpoints для аутентификации ├── v1.py # API версии 1 └── v2.py # API версии 2

Использование API

1. Регистрация пользователя

2. Вход и получение токена

Ответ:

3. Использование токена

Все защищённые endpoints требуют токен в заголовке:

Authorization: Bearer <ваш_токен>

4. Работа с авторами (API v1)

Получить всех авторов

Создать автора

Создать автора с идемпотентностью

Повторный запрос с тем же

Idempotency-Key
вернёт тот же результат без создания дубликата.

Получить автора по ID

Обновить автора

Удалить автора

5. Работа с книгами (API v1)

Получить все книги

Создать книгу

6. Работа с книгами (API v2)

API v2 отличается от v1 дополнительными полями для книг:

Создать книгу с дополнительными полями

Основные принципы REST API

1. Простота и предсказуемость

  • Используются стандартные HTTP методы: GET, POST, PUT, DELETE
  • Понятные имена ресурсов:
    /authors
    ,
    /books
  • Единообразная структура URL:
    /api/v1/resource/{id}

2. Версионность

API поддерживает несколько версий:

  • /api/v1/
    - базовая версия
  • /api/v2/
    - версия с дополнительными полями

Почему версионность важна:

  • Позволяет развивать API без поломки существующих клиентов
  • Старые версии продолжают работать
  • Новые версии могут добавлять функциональность

3. Идемпотентность

Идемпотентные операции:

  • GET - всегда возвращает тот же результат
  • PUT - повторный запрос с теми же данными не меняет состояние
  • DELETE - повторное удаление не меняет состояние

Не идемпотентные операции:

  • POST - каждый запрос создаёт новый ресурс

Решение: Использование заголовка

Idempotency-Key
для POST запросов. Повторный запрос с тем же ключом возвращает сохранённый результат.

4. Rate Limiting

Ограничение частоты запросов защищает API от перегрузки.

Лимиты:

  • 10 запросов в минуту на IP адрес

Заголовки ответа:

  • X-RateLimit-Limit
    - максимальное количество запросов
  • X-RateLimit-Remaining
    - оставшееся количество запросов
  • Retry-After
    - время до следующего разрешённого запроса (при превышении лимита)

При превышении лимита:

  • Статус код: 429 (Too Many Requests)
  • Заголовок
    Retry-After
    указывает время ожидания

5. Аутентификация

Выбранный способ: JWT (JSON Web Token)

Обоснование выбора:

  1. Stateless (без состояния)

    • Сервер не хранит сессии
    • Легко масштабировать на несколько серверов
  2. Безопасность

    • Токен подписан секретным ключом
    • Можно включить время истечения
    • Данные пользователя в токене (не нужно обращаться к БД)
  3. Стандартность

    • Широко используется в REST API
    • Поддержка в большинстве языков и фреймворков
  4. Гибкость

    • Можно добавить роли и права доступа
    • Легко интегрировать с микросервисами

Альтернативы и почему они не выбраны:

  • API-ключ: Проще, но менее безопасен, нет срока действия
  • OAuth 2.0: Сложнее для простых случаев, избыточен для внутреннего API
  • Session-based: Требует хранения сессий, сложнее масштабировать

6. Документация

Автоматическая документация в формате OpenAPI (Swagger):

  • Доступна по адресу
    /docs
  • Включает все endpoints, схемы запросов и ответов
  • Позволяет тестировать API прямо в браузере

Ломающие изменения (Breaking Changes)

Ломающие изменения - это изменения, которые нарушают обратную совместимость API.

Примеры ломающих изменений:

  1. Удаление поля из ответа

    Клиенты, ожидающие поле "author", сломаются.

  2. Изменение типа поля

  3. Изменение обязательности поля

  4. Изменение URL структуры

    // Было: /api/books/1 // Стало: /api/v1/books/1

Почему их стоит избегать:

  • Клиенты перестают работать
  • Требуется обновление всех клиентов одновременно
  • Сложность миграции
  • Плохой пользовательский опыт

Аддитивные изменения (не ломающие):

В нашем проекте v2 добавляет новые поля, которые являются опциональными:

  • description
    - опциональное поле
  • pages
    - опциональное поле
  • rating
    - опциональное поле

Старые клиенты продолжают работать, новые могут использовать дополнительные поля.

Пояснения к коду

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

main.py

Главный файл, который:

  • Создаёт экземпляр FastAPI приложения
  • Настраивает CORS (для работы с фронтендом)
  • Подключает middleware для rate limiting
  • Регистрирует все маршруты (routers)

app/models.py

Pydantic модели для:

  • Валидации входных данных
  • Сериализации выходных данных
  • Автоматической генерации документации

Пример:

Если передать неверные данные, FastAPI автоматически вернёт ошибку валидации.

app/database.py

Внутреннее хранилище данных (in-memory). В реальном приложении здесь был бы код для работы с БД (PostgreSQL, MySQL).

Функции:

  • create_author()
    - создание автора
  • get_author()
    - получение автора
  • check_idempotency_key()
    - проверка ключа идемпотентности

app/auth.py

Модуль аутентификации:

  • get_password_hash()
    - хеширование пароля (bcrypt)
  • verify_password()
    - проверка пароля
  • create_access_token()
    - создание JWT токена
  • get_current_user()
    - получение пользователя из токена

Как работает JWT:

  1. Пользователь вводит логин/пароль
  2. Сервер проверяет и создаёт токен с данными пользователя
  3. Токен отправляется клиенту
  4. Клиент отправляет токен в заголовке
    Authorization: Bearer <token>
  5. Сервер проверяет токен и извлекает данные пользователя

app/routers/v1.py
и
app/routers/v2.py

Маршруты (endpoints) для каждой версии API.

CRUD операции:

  • Create (POST) - создание ресурса
  • Read (GET) - чтение ресурса
  • Update (PUT) - обновление ресурса
  • Delete (DELETE) - удаление ресурса

Защита endpoints:

Depends(get_current_user)
означает, что endpoint требует аутентификации.

Идемпотентность:

Извлекает ключ из заголовка и проверяет, не использовался ли он ранее.

app/middleware/rate_limit.py

Middleware для rate limiting:

  • Отслеживает количество запросов от каждого IP
  • Блокирует при превышении лимита
  • Добавляет заголовки в ответ

Тестирование API

Использование Swagger UI

  1. Откройте http://localhost:8000/docs
  2. Нажмите "Authorize" и введите токен
  3. Выберите endpoint и нажмите "Try it out"
  4. Заполните параметры и нажмите "Execute"

Использование curl

Использование Python requests

Развёртывание на GitVerse

1. Создание аккаунта

  1. Перейдите на https://gitverse.ru
  2. Зарегистрируйтесь или войдите

2. Создание репозитория

  1. Нажмите кнопку "New" или "+" → "New repository"
  2. Введите название репозитория (например,
    library-rest-api
    )
  3. Выберите "Public" или "Private"
  4. Нажмите "Create repository"

3. Загрузка кода

Вариант 1: Через веб-интерфейс

  1. В репозитории нажмите "Upload files"
  2. Перетащите все файлы проекта
  3. Нажмите "Commit changes"

Вариант 2: Через Git (рекомендуется)

Если у вас установлен Git:

Если GitVerse попросит авторизацию:

  • Используйте логин и пароль от GitVerse
  • Или создайте Personal Access Token в настройках профиля

4. Добавление README

README.md уже включён в проект и будет автоматически отображаться на главной странице репозитория.

5. Проверка

Откройте ваш репозиторий на GitVerse и убедитесь, что все файлы загружены.

Команды для защиты лабораторной

Запуск приложения

Проверка работы

  1. Откройте браузер: http://localhost:8000/docs
  2. Зарегистрируйте пользователя через
    /api/auth/register
  3. Получите токен через
    /api/auth/login
  4. Протестируйте endpoints для книг и авторов

Демонстрация функций

Версионность:

  • Показать
    /api/v1/books
    и
    /api/v2/books
  • Объяснить разницу (дополнительные поля в v2)

Идемпотентность:

  • Создать книгу с
    Idempotency-Key: test-123
  • Повторить запрос с тем же ключом
  • Показать, что дубликат не создался

Rate Limiting:

  • Сделать 11 запросов подряд
  • Показать ошибку 429 и заголовок
    Retry-After

Аутентификация:

  • Показать запрос без токена (ошибка 401)
  • Показать запрос с токеном (успех)

Выводы

  1. REST API должен быть простым и предсказуемым - использование стандартных HTTP методов и понятных URL
  2. Версионность критична - позволяет развивать API без поломки клиентов
  3. Идемпотентность важна - предотвращает дублирование операций
  4. Rate limiting защищает - от перегрузки и злоупотреблений
  5. Документация обязательна - автоматическая генерация через OpenAPI упрощает использование
  6. JWT подходит для REST API - stateless, безопасный, масштабируемый

Дополнительные материалы

Контакты

Для вопросов по проекту обращайтесь к автору.


Примечание: Это учебный проект. В продакшене необходимо:

  • Использовать реальную БД (PostgreSQL, MySQL)
  • Хранить секретные ключи в переменных окружения
  • Настроить HTTPS
  • Использовать Redis для rate limiting
  • Добавить логирование и мониторинг