library-rest-api
Описание
REST API для библиотеки - лабораторная работа
Языки
- Python100%
REST API для библиотеки
Описание проекта
Это REST API для управления библиотекой, реализованное на Python с использованием FastAPI. Проект демонстрирует принципы проектирования REST API: простота, стабильность, версионность, идемпотентность, ограничение частоты запросов и документация.
Предметная область
Библиотека - система для управления книгами и авторами.
Сущности:
-
Авторы (Authors)
- ID (уникальный идентификатор)
- Имя
- Год рождения
-
Книги (Books)
- ID (уникальный идентификатор)
- Название
- Автор (связь с сущностью Author)
- ISBN
- Год издания
- Статус (доступна, взята на руки, зарезервирована)
- В v2 добавлены: описание, количество страниц, рейтинг
-
Пользователи (Users)
- ID
- Имя пользователя
- Хешированный пароль
Технологии
- Python 3.8+
- FastAPI - современный веб-фреймворк для создания API
- Uvicorn - ASGI сервер для запуска приложения
- Pydantic - валидация данных
- JWT - аутентификация через JSON Web Tokens
- bcrypt - хеширование паролей
- slowapi - rate limiting
Установка и запуск
1. Установка зависимостей
2. Запуск сервера
Примечание: Если команда не найдена, используйте вместо просто .
Сервер запустится на
3. Доступ к документации
После запуска доступна автоматическая документация:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
Структура проекта
.
├── 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
└── internal.py # Внутренний API (ЛР2)
Использование API
1. Регистрация пользователя
2. Вход и получение токена
Ответ:
3. Использование токена
Все защищённые endpoints требуют токен в заголовке:
Authorization: Bearer <ваш_токен>
4. Работа с авторами (API v1)
Получить всех авторов
Создать автора
Создать автора с идемпотентностью
Повторный запрос с тем же вернёт тот же результат без создания дубликата.
Получить автора по 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 - каждый запрос создаёт новый ресурс
Решение: Использование заголовка для POST запросов. Повторный запрос с тем же ключом возвращает сохранённый результат.
4. Rate Limiting
Ограничение частоты запросов защищает API от перегрузки.
Лимиты:
- 10 запросов в минуту на IP адрес
Заголовки ответа:
- максимальное количество запросовX-RateLimit-Limit- оставшееся количество запросовX-RateLimit-Remaining- альтернативный заголовок (ЛР2)X-Limit-Remaining- время до следующего разрешённого запроса (при превышении лимита)Retry-After
При превышении лимита:
- Статус код: 429 (Too Many Requests)
- Заголовок
указывает время ожиданияRetry-After
5. Пагинация (ЛР2)
Для endpoints, возвращающих списки ресурсов, реализована пагинация через параметры и .
Использование:
Параметры:
(опционально) - смещение (с какого элемента начинать), по умолчанию 0offset(опционально) - количество элементов на странице, максимум 100limit
Ответ с пагинацией:
Обратная совместимость:
- Если параметры
иoffsetне указаны, возвращается весь список (как в ЛР1)limit - Старые клиенты продолжают работать без изменений
Обоснование выбора offset/limit:
- Простота реализации и понимания
- Прямой доступ к любой странице (не нужно проходить через предыдущие)
- Стандартный подход в REST API
- Подходит для небольших и средних объёмов данных
6. Опциональные поля (ЛР2)
Реализована возможность выбора полей, которые возвращает API, через параметр .
Использование:
Параметры:
(опционально) - список полей через запятуюinclude
Пример:
Опциональные поля:
- Для авторов:
,id,name,birth_yearcreated_at - Для книг:
,id,title,author_id,isbn,year,status,authorcreated_at - Для книг v2: дополнительно
,description,pagesrating
Обоснование:
- Уменьшает размер ответа (экономия трафика)
- Ускоряет обработку на клиенте
- Позволяет клиентам запрашивать только нужные данные
- Особенно полезно для мобильных приложений
7. Внутренний API (ЛР2)
Реализован внутренний API для административных и служебных целей.
Endpoints:
- статистика системыGET /api/internal/stats- проверка работоспособностиGET /api/internal/health
Аутентификация:
- Упрощённая аутентификация через API-ключ
- Заголовок: X-Internal-API-Key: internal-secret-key-12345
Пример запроса:
Особенности внутреннего API:
- Упрощённая аутентификация (API-ключ вместо JWT)
- Прямой доступ к данным без бизнес-логики
- Оптимизированные запросы для систем мониторинга
- Детальная статистика и метрики
Обоснование упрощений:
- Не требует полной аутентификации пользователя (быстрее)
- Предназначен для автоматизированных систем, а не пользователей
- Меньше накладных расходов на проверки
- Используется системами мониторинга, которые делают частые запросы
Пример ответа :
8. Аутентификация
Выбранный способ: JWT (JSON Web Token)
Обоснование выбора:
-
Stateless (без состояния)
- Сервер не хранит сессии
- Легко масштабировать на несколько серверов
-
Безопасность
- Токен подписан секретным ключом
- Можно включить время истечения
- Данные пользователя в токене (не нужно обращаться к БД)
-
Стандартность
- Широко используется в REST API
- Поддержка в большинстве языков и фреймворков
-
Гибкость
- Можно добавить роли и права доступа
- Легко интегрировать с микросервисами
Альтернативы и почему они не выбраны:
- API-ключ: Проще, но менее безопасен, нет срока действия
- OAuth 2.0: Сложнее для простых случаев, избыточен для внутреннего API
- Session-based: Требует хранения сессий, сложнее масштабировать
9. Документация
Автоматическая документация в формате OpenAPI (Swagger):
- Доступна по адресу /docs
- Включает все endpoints, схемы запросов и ответов
- Позволяет тестировать API прямо в браузере
Ломающие изменения (Breaking Changes)
Ломающие изменения - это изменения, которые нарушают обратную совместимость API.
Примеры ломающих изменений:
-
Удаление поля из ответа
Клиенты, ожидающие поле "author", сломаются.
-
Изменение типа поля
-
Изменение обязательности поля
-
Изменение 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
Модуль аутентификации:
- хеширование пароля (bcrypt)get_password_hash()- проверка пароляverify_password()- создание JWT токенаcreate_access_token()- получение пользователя из токенаget_current_user()
Как работает JWT:
- Пользователь вводит логин/пароль
- Сервер проверяет и создаёт токен с данными пользователя
- Токен отправляется клиенту
- Клиент отправляет токен в заголовке Authorization: Bearer <token>
- Сервер проверяет токен и извлекает данные пользователя
app/routers/v1.py и app/routers/v2.py
Маршруты (endpoints) для каждой версии API.
CRUD операции:
- Create (POST) - создание ресурса
- Read (GET) - чтение ресурса
- Update (PUT) - обновление ресурса
- Delete (DELETE) - удаление ресурса
Защита endpoints:
означает, что endpoint требует аутентификации.
Идемпотентность:
Извлекает ключ из заголовка и проверяет, не использовался ли он ранее.
app/middleware/rate_limit.py
Middleware для rate limiting:
- Отслеживает количество запросов от каждого IP
- Блокирует при превышении лимита
- Добавляет заголовки в ответ
Тестирование API
Использование Swagger UI
- Откройте http://localhost:8000/docs
- Нажмите "Authorize" и введите токен
- Выберите endpoint и нажмите "Try it out"
- Заполните параметры и нажмите "Execute"
Использование curl
Использование Python requests
Развёртывание на GitVerse
1. Создание аккаунта
- Перейдите на https://gitverse.ru
- Зарегистрируйтесь или войдите
2. Создание репозитория
- Нажмите кнопку "New" или "+" → "New repository"
- Введите название репозитория (например,
)library-rest-api - Выберите "Public" или "Private"
- Нажмите "Create repository"
3. Загрузка кода
Вариант 1: Через веб-интерфейс
- В репозитории нажмите "Upload files"
- Перетащите все файлы проекта
- Нажмите "Commit changes"
Вариант 2: Через Git (рекомендуется)
Если у вас установлен Git:
Если GitVerse попросит авторизацию:
- Используйте логин и пароль от GitVerse
- Или создайте Personal Access Token в настройках профиля
4. Добавление README
README.md уже включён в проект и будет автоматически отображаться на главной странице репозитория.
5. Проверка
Откройте ваш репозиторий на GitVerse и убедитесь, что все файлы загружены.
Команды для защиты лабораторной
Запуск приложения
Проверка работы
- Откройте браузер: http://localhost:8000/docs
- Зарегистрируйте пользователя через /api/auth/register
- Получите токен через /api/auth/login
- Протестируйте endpoints для книг и авторов
Демонстрация функций
Версионность:
- Показать
и/api/v1/books/api/v2/books - Объяснить разницу (дополнительные поля в v2)
Идемпотентность:
- Создать книгу с Idempotency-Key: test-123
- Повторить запрос с тем же ключом
- Показать, что дубликат не создался
Rate Limiting:
- Сделать 11 запросов подряд
- Показать ошибку 429 и заголовок Retry-After
Аутентификация:
- Показать запрос без токена (ошибка 401)
- Показать запрос с токеном (успех)
Выводы
- REST API должен быть простым и предсказуемым - использование стандартных HTTP методов и понятных URL
- Версионность критична - позволяет развивать API без поломки клиентов
- Идемпотентность важна - предотвращает дублирование операций
- Rate limiting защищает - от перегрузки и злоупотреблений
- Документация обязательна - автоматическая генерация через OpenAPI упрощает использование
- JWT подходит для REST API - stateless, безопасный, масштабируемый
Дополнительные материалы
Примечание: Это учебный проект. В продакшене необходимо:
- Использовать реальную БД (PostgreSQL, MySQL)
- Хранить секретные ключи в переменных окружения
- Настроить HTTPS
- Использовать Redis для rate limiting
- Добавить логирование и мониторинг