# API Сервиса Питания (Nutrition Service) Сервис питания предоставляет API для работы с данными о питании, включая поиск продуктов питания, добавление продуктов в дневник питания, отслеживание потребления воды и физической активности. ## Основные функции - Поиск продуктов питания через FatSecret API - Отслеживание потребления пищи и питательных веществ - Учет потребления воды - Отслеживание физической активности - Установка и отслеживание целей по питанию и активности ## Базовый URL ``` http://localhost:8006/api/v1/nutrition/ ``` ## Swagger-документация Интерактивная документация API доступна через Swagger UI по следующим URL: ``` http://localhost:8006/docs ``` или через ReDoc: ``` http://localhost:8006/redoc ``` > **Примечание**: Swagger-документация доступна только при запущенном сервисе питания. Если сервис не запущен, страница документации будет недоступна. ### Использование Swagger UI 1. Откройте URL `http://localhost:8006/docs` в браузере 2. Авторизуйтесь с помощью кнопки "Authorize" в верхней части страницы: - Введите ваш JWT токен в формате: `Bearer ` - Нажмите "Authorize" 3. Теперь вы можете тестировать все эндпоинты API непосредственно через Swagger UI: - Выберите нужный эндпоинт - Заполните параметры запроса - Нажмите "Execute" для отправки запроса ![Swagger UI Example](https://swagger.io/swagger/media/images/swagger-ui-example.png) ## Эндпоинты ### Поиск продуктов #### Поиск по названию ```http POST /api/v1/nutrition/search ``` Параметры запроса: ```json { "query": "яблоко", "page_number": 0, "max_results": 10 } ``` Ответ: ```json [ { "id": 1, "uuid": "123e4567-e89b-12d3-a456-426614174000", "fatsecret_id": "35718", "name": "Apple", "brand": null, "description": "A common fruit", "food_type": "Generic", "serving_size": "100g", "serving_weight_grams": 100.0, "calories": 52.0, "protein_grams": 0.26, "fat_grams": 0.17, "carbs_grams": 13.81, "fiber_grams": 2.4, "sugar_grams": 10.39, "sodium_mg": 1.0, "cholesterol_mg": 0.0, "ingredients": null, "is_verified": true, "created_at": "2025-10-16T23:10:00" } ] ``` #### Получение информации о продукте ```http GET /api/v1/nutrition/food/{food_id} ``` Ответ: ```json { "id": 1, "uuid": "123e4567-e89b-12d3-a456-426614174000", "fatsecret_id": "35718", "name": "Apple", "brand": null, "description": "A common fruit", "food_type": "Generic", "serving_size": "100g", "serving_weight_grams": 100.0, "calories": 52.0, "protein_grams": 0.26, "fat_grams": 0.17, "carbs_grams": 13.81, "fiber_grams": 2.4, "sugar_grams": 10.39, "sodium_mg": 1.0, "cholesterol_mg": 0.0, "ingredients": null, "is_verified": true, "created_at": "2025-10-16T23:10:00" } ``` ### Дневник питания #### Добавление записи в дневник питания ```http POST /api/v1/nutrition/diary ``` Параметры запроса: ```json { "food_item_id": 1, "entry_date": "2025-10-16", "meal_type": "breakfast", "quantity": 1.5, "unit": "piece", "notes": "Morning apple" } ``` Ответ: ```json { "id": 1, "uuid": "123e4567-e89b-12d3-a456-426614174000", "user_id": 42, "entry_date": "2025-10-16", "meal_type": "breakfast", "food_item_id": 1, "custom_food_name": null, "quantity": 1.5, "unit": "piece", "calories": 78.0, "protein_grams": 0.39, "fat_grams": 0.255, "carbs_grams": 20.715, "notes": "Morning apple", "created_at": "2025-10-16T23:15:00" } ``` #### Получение записей дневника за день ```http GET /api/v1/nutrition/diary?date=2025-10-16 ``` Ответ: ```json [ { "id": 1, "uuid": "123e4567-e89b-12d3-a456-426614174000", "user_id": 42, "entry_date": "2025-10-16", "meal_type": "breakfast", "food_item_id": 1, "custom_food_name": null, "quantity": 1.5, "unit": "piece", "calories": 78.0, "protein_grams": 0.39, "fat_grams": 0.255, "carbs_grams": 20.715, "notes": "Morning apple", "created_at": "2025-10-16T23:15:00" } ] ``` #### Получение сводки за день ```http GET /api/v1/nutrition/summary?date=2025-10-16 ``` Ответ: ```json { "date": "2025-10-16", "total_calories": 2150.5, "total_protein": 85.2, "total_fat": 65.4, "total_carbs": 275.3, "water_consumed_ml": 1500, "activity_minutes": 45, "calories_burned": 350, "entries_by_meal": { "breakfast": [ { "id": 1, "food_name": "Apple", "quantity": 1.5, "unit": "piece", "calories": 78.0 } ], "lunch": [...], "dinner": [...], "snack": [...] } } ``` ### Потребление воды #### Добавление записи о потреблении воды ```http POST /api/v1/nutrition/water ``` Параметры запроса: ```json { "amount_ml": 250, "entry_date": "2025-10-16", "notes": "Morning glass" } ``` Ответ: ```json { "id": 1, "uuid": "123e4567-e89b-12d3-a456-426614174000", "user_id": 42, "entry_date": "2025-10-16", "amount_ml": 250, "entry_time": "2025-10-16T08:30:00", "notes": "Morning glass" } ``` #### Получение записей о потреблении воды за день ```http GET /api/v1/nutrition/water?date=2025-10-16 ``` Ответ: ```json [ { "id": 1, "uuid": "123e4567-e89b-12d3-a456-426614174000", "user_id": 42, "entry_date": "2025-10-16", "amount_ml": 250, "entry_time": "2025-10-16T08:30:00", "notes": "Morning glass" }, { "id": 2, "uuid": "223e4567-e89b-12d3-a456-426614174001", "user_id": 42, "entry_date": "2025-10-16", "amount_ml": 500, "entry_time": "2025-10-16T12:15:00", "notes": "Lunch" } ] ``` ### Физическая активность #### Добавление записи о физической активности ```http POST /api/v1/nutrition/activity ``` Параметры запроса: ```json { "entry_date": "2025-10-16", "activity_type": "running", "duration_minutes": 30, "distance_km": 5.2, "intensity": "medium", "notes": "Morning run" } ``` Ответ: ```json { "id": 1, "uuid": "123e4567-e89b-12d3-a456-426614174000", "user_id": 42, "entry_date": "2025-10-16", "activity_type": "running", "duration_minutes": 30, "calories_burned": 300.5, "distance_km": 5.2, "steps": null, "intensity": "medium", "notes": "Morning run", "created_at": "2025-10-16T09:00:00" } ``` #### Получение записей об активности за день ```http GET /api/v1/nutrition/activity?date=2025-10-16 ``` Ответ: ```json [ { "id": 1, "uuid": "123e4567-e89b-12d3-a456-426614174000", "user_id": 42, "entry_date": "2025-10-16", "activity_type": "running", "duration_minutes": 30, "calories_burned": 300.5, "distance_km": 5.2, "steps": null, "intensity": "medium", "notes": "Morning run", "created_at": "2025-10-16T09:00:00" } ] ``` ### Цели по питанию и активности #### Установка целей ```http POST /api/v1/nutrition/goals ``` Параметры запроса: ```json { "daily_calorie_goal": 2000, "protein_goal_grams": 100, "fat_goal_grams": 65, "carbs_goal_grams": 250, "water_goal_ml": 2500, "activity_goal_minutes": 45, "weight_goal_kg": 75.5, "goal_type": "lose_weight" } ``` Ответ: ```json { "id": 1, "user_id": 42, "daily_calorie_goal": 2000, "protein_goal_grams": 100, "fat_goal_grams": 65, "carbs_goal_grams": 250, "water_goal_ml": 2500, "activity_goal_minutes": 45, "weight_goal_kg": 75.5, "goal_type": "lose_weight", "created_at": "2025-10-16T10:00:00", "updated_at": "2025-10-16T10:00:00" } ``` #### Получение текущих целей ```http GET /api/v1/nutrition/goals ``` Ответ: ```json { "id": 1, "user_id": 42, "daily_calorie_goal": 2000, "protein_goal_grams": 100, "fat_goal_grams": 65, "carbs_goal_grams": 250, "water_goal_ml": 2500, "activity_goal_minutes": 45, "weight_goal_kg": 75.5, "goal_type": "lose_weight", "created_at": "2025-10-16T10:00:00", "updated_at": "2025-10-16T10:00:00" } ``` ## Коды ошибок | Код | Описание | |-----|----------| | 400 | Некорректный запрос | | 401 | Не авторизован | | 403 | Доступ запрещен | | 404 | Ресурс не найден | | 500 | Внутренняя ошибка сервера | ## Аутентификация Все запросы к API требуют JWT-токен в заголовке Authorization: ``` Authorization: Bearer ``` Токен можно получить через сервис авторизации (User Service) по эндпоинту `/api/v1/auth/login`. ## Интеграции Сервис питания интегрирован с API FatSecret для получения данных о продуктах питания и их пищевой ценности. Работа с API FatSecret осуществляется через OAuth 1.0 аутентификацию с использованием ключей, указанных в конфигурации приложения. ## Тестирование API ### Тестирование через Swagger UI Самый простой способ протестировать API - использовать встроенный интерфейс Swagger UI: 1. Убедитесь, что сервис питания запущен: ```bash # Запуск всех сервисов ./start_services.sh ``` 2. Откройте в браузере URL: `http://localhost:8006/docs` 3. Авторизуйтесь: - Нажмите на кнопку "Authorize" в правом верхнем углу - Введите ваш JWT токен в формате `Bearer ` - Нажмите "Authorize" 4. Теперь вы можете интерактивно тестировать все эндпоинты: - Выберите нужный эндпоинт - Заполните параметры запроса - Нажмите "Execute" - Просмотрите результат запроса и код ответа ### Настройка и запуск через CLI 1. Убедитесь, что все необходимые сервисы запущены: ```bash # Запуск всех сервисов ./start_services.sh ``` 2. Получите токен аутентификации: ```bash # Регистрация нового пользователя curl -X POST http://localhost:8001/api/v1/auth/register -H "Content-Type: application/json" -d '{ "email": "test_user@example.com", "username": "test_user", "password": "Test123!", "first_name": "Test", "last_name": "User", "phone": "+79991234567" }' | jq # Вход и получение токена curl -X POST http://localhost:8001/api/v1/auth/login -H "Content-Type: application/json" -d '{ "username": "test_user", "password": "Test123!" }' | jq ``` 3. Сохраните полученный токен в переменную для дальнейшего использования: ```bash export TOKEN="ваш_полученный_jwt_токен" ``` ### Примеры запросов #### Поиск продуктов ```bash # Поиск продуктов по названию curl -X POST http://localhost:8006/api/v1/nutrition/search \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $TOKEN" \ -d '{ "query": "apple", "max_results": 5 }' | jq ``` #### Работа с дневником питания ```bash # Добавление записи в дневник питания curl -X POST http://localhost:8006/api/v1/nutrition/diary \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $TOKEN" \ -d '{ "food_item_id": 1, "entry_date": "2025-10-16", "meal_type": "breakfast", "quantity": 1.5, "unit": "piece", "notes": "Morning apple" }' | jq # Получение дневника за день curl -X GET http://localhost:8006/api/v1/nutrition/diary?date=2025-10-16 \ -H "Authorization: Bearer $TOKEN" | jq ``` #### Работа с водой ```bash # Добавление записи о потреблении воды curl -X POST http://localhost:8006/api/v1/nutrition/water \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $TOKEN" \ -d '{ "amount_ml": 250, "entry_date": "2025-10-16", "notes": "Morning glass" }' | jq # Получение записей о потреблении воды за день curl -X GET http://localhost:8006/api/v1/nutrition/water?date=2025-10-16 \ -H "Authorization: Bearer $TOKEN" | jq ``` #### Работа с активностью ```bash # Добавление записи о физической активности curl -X POST http://localhost:8006/api/v1/nutrition/activity \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $TOKEN" \ -d '{ "entry_date": "2025-10-16", "activity_type": "running", "duration_minutes": 30, "distance_km": 5.2, "intensity": "medium", "notes": "Morning run" }' | jq # Получение записей об активности за день curl -X GET http://localhost:8006/api/v1/nutrition/activity?date=2025-10-16 \ -H "Authorization: Bearer $TOKEN" | jq ``` ### Автоматизированное тестирование В папке `tests` есть скрипты для автоматизированного тестирования API: ```bash # Запуск всех тестов для nutrition service cd tests ./test_nutrition_service.sh # Запуск тестов через Python python test_nutrition_api.py ``` Для непосредственного тестирования FatSecret API можно использовать скрипт в корне проекта: ```bash # Тестирование FatSecret API python test_fatsecret_api_oauth1.py ```