Files
marketing-parser/FRONTEND_API_GUIDE.md
T
2025-09-14 18:10:45 +05:00

656 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Руководство по API для фронтенда
## Обзор изменений
После рефакторинга старый `ParserController` был разделен на три специализированных контроллера для лучшей организации и масштабируемости:
- **`MarketItemController`** (`/api/items`) - для получения данных
- **`ParserAdminController`** (`/api/admin/parsers`) - для управления парсерами
- **`HealthCheckController`** (`/api/health`) - для мониторинга системы
---
## 📊 MarketItemController - Получение данных
**Базовый URL**: `/api/items`
### 1. Получение списка новостей с фильтрацией и пагинацией
```http
GET /api/items
```
**Параметры запроса:**
- `sourceName` (optional) - фильтр по источнику (например: "Kursiv Media", "Kapital.kz", "LSM.kz", "РБК", "Ведомости")
- `startDate` (optional) - начальная дата в формате ISO (например: "2024-01-01T00:00:00")
- `endDate` (optional) - конечная дата в формате ISO (например: "2024-12-31T23:59:59")
- `page` (optional) - номер страницы (по умолчанию: 0)
- `size` (optional) - размер страницы (по умолчанию: 20)
- `sort` (optional) - сортировка (по умолчанию: "publishedAt,desc")
**Примеры запросов:**
```javascript
// Получить все новости
fetch('/api/items');
// Получить новости с пагинацией
fetch('/api/items?page=0&size=10');
// Получить новости от конкретного источника
fetch('/api/items?sourceName=Kursiv Media');
// Получить новости за последние 7 дней
const weekAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString();
fetch(`/api/items?startDate=${weekAgo}`);
// Получить новости с сортировкой по дате (старые сначала)
fetch('/api/items?sort=publishedAt,asc');
```
**Ответ:**
```json
{
"success": true,
"message": "Записи получены успешно",
"data": {
"content": [
{
"id": "64f1a2b3c4d5e6f7g8h9i0j1",
"sourceName": "Kursiv Media",
"url": "https://kursiv.media/news/example",
"title": "Заголовок новости",
"publishedAt": "2024-01-15T10:30:00",
"addedAt": "2024-01-15T10:35:00",
"rawText": "Текст новости без HTML тегов",
"hash": "abc123def456...",
"category": "Бизнес",
"analytics": {
"summary": null,
"sentiment": null,
"tags": [],
"entities": {}
}
}
],
"pageable": {
"sort": {
"sorted": true,
"unsorted": false
},
"pageNumber": 0,
"pageSize": 20,
"offset": 0,
"paged": true,
"unpaged": false
},
"totalElements": 150,
"totalPages": 8,
"last": false,
"first": true,
"numberOfElements": 20,
"size": 20,
"number": 0,
"empty": false
}
}
```
### 2. Получение новости по ID
```http
GET /api/items/{id}
```
**Пример:**
```javascript
fetch('/api/items/64f1a2b3c4d5e6f7g8h9i0j1');
```
**Ответ:**
```json
{
"success": false,
"message": "Функция поиска по ID пока не реализована"
}
```
### 3. Получение статистики
```http
GET /api/items/stats
```
**Ответ:**
```json
{
"success": true,
"message": "Статистика получена успешно",
"data": {
"totalItems": 1250,
"sourceStatistics": {
"Kursiv Media": 300,
"Kapital.kz": 250,
"LSM.kz": 200,
"РБК": 300,
"Ведомости": 200
},
"lastUpdate": "2024-01-15T10:35:00"
}
}
```
### 4. Получение списка источников
```http
GET /api/items/sources
```
**Ответ:**
```json
{
"success": true,
"message": "Источники получены успешно",
"data": ["Kursiv Media", "Kapital.kz", "LSM.kz", "РБК", "Ведомости"]
}
```
### 5. Получение новостей по конкретному источнику
```http
GET /api/items/source/{sourceName}
```
**Пример:**
```javascript
fetch('/api/items/source/Kursiv Media?page=0&size=10');
```
**Ответ:** Аналогичен ответу от `/api/items`, но только с новостями от указанного источника.
---
## ⚙️ ParserAdminController - Управление парсерами
**Базовый URL**: `/api/admin/parsers`
> ⚠️ **Важно**: Эти эндпоинты предназначены для административных функций и могут потребовать аутентификации в будущем.
### 1. Запуск конкретного парсера
```http
POST /api/admin/parsers/parse/{sourceName}
```
**Доступные источники:**
- `kursiv`
- `kapital`
- `lsm`
- `rbc`
- `vedomosti`
**Пример:**
```javascript
// Запустить парсер Kursiv
fetch('/api/admin/parsers/parse/kursiv', { method: 'POST' });
// Запустить парсер РБК
fetch('/api/admin/parsers/parse/rbc', { method: 'POST' });
```
**Ответ:**
```json
{
"success": true,
"message": "Парсинг kursiv завершен",
"data": {
"source": "kursiv",
"processedItems": 15,
"totalItemsInDb": 1265,
"status": "completed"
}
}
```
### 2. Запуск всех парсеров
```http
POST /api/admin/parsers/parse/all
```
**Пример:**
```javascript
fetch('/api/admin/parsers/parse/all', { method: 'POST' });
```
**Ответ:**
```json
{
"success": true,
"message": "Парсинг всех источников завершен",
"data": [
{
"source": "kursiv",
"processedItems": 12,
"totalItemsInDb": 1277,
"status": "completed"
},
{
"source": "kapital",
"processedItems": 8,
"totalItemsInDb": 1285,
"status": "completed"
},
{
"source": "lsm",
"processedItems": 5,
"totalItemsInDb": 1290,
"status": "completed"
},
{
"source": "rbc",
"processedItems": 20,
"totalItemsInDb": 1310,
"status": "completed"
},
{
"source": "vedomosti",
"processedItems": 7,
"totalItemsInDb": 1317,
"status": "completed"
}
]
}
```
### 3. Получение списка доступных парсеров
```http
GET /api/admin/parsers
```
**Ответ:**
```json
{
"success": true,
"message": "Список парсеров получен",
"data": ["kapital", "kursiv", "lsm", "rbc", "vedomosti"]
}
```
### 4. Получение информации о парсерах
```http
GET /api/admin/parsers/info
```
**Ответ:**
```json
{
"success": true,
"message": "Информация о парсерах получена",
"data": {
"totalParsers": 5,
"availableParsers": ["kapital", "kursiv", "lsm", "rbc", "vedomosti"],
"totalItems": 1317,
"sourceStatistics": {
"Kursiv Media": 300,
"Kapital.kz": 250,
"LSM.kz": 200,
"РБК": 300,
"Ведомости": 200
}
}
}
```
### 5. Проверка существования парсера
```http
GET /api/admin/parsers/exists/{sourceName}
```
**Пример:**
```javascript
fetch('/api/admin/parsers/exists/kursiv');
```
**Ответ:**
```json
{
"success": true,
"message": "Проверка завершена",
"data": true
}
```
---
## 🔍 HealthCheckController - Мониторинг системы
**Базовый URL**: `/api/health`
### 1. Базовая проверка состояния
```http
GET /api/health
```
**Ответ:**
```json
{
"success": true,
"message": "Сервис работает",
"data": {
"status": "UP",
"service": "RSS Parser System",
"timestamp": 1705312500000,
"details": "Enabled - runs every 30 minutes"
}
}
```
### 2. Проверка подключения к MongoDB
```http
GET /api/health/mongodb
```
**Ответ (успех):**
```json
{
"success": true,
"message": "MongoDB подключение успешно",
"data": {
"status": "UP",
"service": "MongoDB подключение успешно",
"timestamp": 1705312500000,
"details": "Всего записей: 1317"
}
}
```
**Ответ (ошибка):**
```json
{
"success": false,
"message": "Ошибка подключения к MongoDB",
"data": {
"status": "DOWN",
"service": "Ошибка подключения к MongoDB: Connection refused",
"timestamp": 1705312500000,
"suggestion": "Проверьте учетные данные в application.properties"
}
}
```
### 3. Информация о планировщике
```http
GET /api/health/scheduler
```
**Ответ:**
```json
{
"success": true,
"message": "Информация о планировщике получена",
"data": {
"schedulerEnabled": true,
"cronExpression": "0 0/30 * * * ?",
"description": "Запуск каждые 30 минут (в 0 и 30 минут каждого часа)",
"nextRun": "Следующий запуск будет в ближайшие 0 или 30 минут часа",
"activeParsers": ["kapital", "kursiv", "lsm", "rbc", "vedomosti"],
"totalParsers": 5,
"sources": ["Kursiv Media", "Kapital.kz", "LSM.kz", "РБК", "Ведомости"]
}
}
```
### 4. Общая информация о системе
```http
GET /api/health/system
```
**Ответ:**
```json
{
"success": true,
"message": "Информация о системе получена",
"data": {
"parsers": {
"total": 5,
"available": ["kapital", "kursiv", "lsm", "rbc", "vedomosti"]
},
"data": {
"totalItems": 1317,
"sourceStatistics": {
"Kursiv Media": 300,
"Kapital.kz": 250,
"LSM.kz": 200,
"РБК": 300,
"Ведомости": 200
}
},
"system": {
"javaVersion": "17.0.2",
"osName": "Linux",
"osVersion": "5.4.0-74-generic",
"uptime": 1705312500000
}
}
}
```
### 5. Проверка состояния парсеров
```http
GET /api/health/parsers
```
**Ответ:**
```json
{
"success": true,
"message": "Проверка парсеров завершена",
"data": {
"totalParsers": 5,
"availableParsers": ["kapital", "kursiv", "lsm", "rbc", "vedomosti"],
"status": "UP",
"message": "Все парсеры доступны"
}
}
```
---
## 🚀 Примеры использования для фронтенда
### React/JavaScript примеры
```javascript
// Сервис для работы с API
class NewsApiService {
constructor(baseUrl = '') {
this.baseUrl = baseUrl;
}
// Получить новости с фильтрацией
async getNews(filters = {}) {
const params = new URLSearchParams();
if (filters.sourceName) params.append('sourceName', filters.sourceName);
if (filters.startDate) params.append('startDate', filters.startDate);
if (filters.endDate) params.append('endDate', filters.endDate);
if (filters.page !== undefined) params.append('page', filters.page);
if (filters.size) params.append('size', filters.size);
if (filters.sort) params.append('sort', filters.sort);
const response = await fetch(`${this.baseUrl}/api/items?${params}`);
return response.json();
}
// Получить статистику
async getStats() {
const response = await fetch(`${this.baseUrl}/api/items/stats`);
return response.json();
}
// Получить источники
async getSources() {
const response = await fetch(`${this.baseUrl}/api/items/sources`);
return response.json();
}
// Запустить парсер (админ функция)
async runParser(sourceName) {
const response = await fetch(
`${this.baseUrl}/api/admin/parsers/parse/${sourceName}`,
{
method: 'POST',
}
);
return response.json();
}
// Запустить все парсеры (админ функция)
async runAllParsers() {
const response = await fetch(
`${this.baseUrl}/api/admin/parsers/parse/all`,
{
method: 'POST',
}
);
return response.json();
}
// Проверить состояние системы
async getHealthStatus() {
const response = await fetch(`${this.baseUrl}/api/health`);
return response.json();
}
}
// Использование
const apiService = new NewsApiService();
// Получить последние новости
const news = await apiService.getNews({
page: 0,
size: 20,
sort: 'publishedAt,desc',
});
// Получить новости от конкретного источника
const kursivNews = await apiService.getNews({
sourceName: 'Kursiv Media',
page: 0,
size: 10,
});
// Получить новости за последнюю неделю
const weekAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString();
const recentNews = await apiService.getNews({
startDate: weekAgo,
sort: 'publishedAt,desc',
});
```
### Vue.js примеры
```javascript
// composable для работы с API
export function useNewsApi() {
const baseUrl = '';
const getNews = async (filters = {}) => {
const params = new URLSearchParams();
Object.entries(filters).forEach(([key, value]) => {
if (value !== undefined && value !== null) {
params.append(key, value);
}
});
const response = await fetch(`${baseUrl}/api/items?${params}`);
return response.json();
};
const getStats = async () => {
const response = await fetch(`${baseUrl}/api/items/stats`);
return response.json();
};
const getSources = async () => {
const response = await fetch(`${baseUrl}/api/items/sources`);
return response.json();
};
return {
getNews,
getStats,
getSources,
};
}
```
---
## 📝 Важные замечания
1. **Пагинация**: Все эндпоинты для получения данных поддерживают пагинацию через параметры `page` и `size`.
2. **Сортировка**: По умолчанию новости сортируются по дате публикации (новые сначала). Можно изменить через параметр `sort`.
3. **Фильтрация**: Поддерживается фильтрация по источнику и диапазону дат.
4. **Формат дат**: Используйте ISO 8601 формат для дат (например: "2024-01-15T10:30:00").
5. **Обработка ошибок**: Все ответы содержат поле `success` для проверки успешности операции.
6. **Административные функции**: Эндпоинты `/api/admin/parsers/*` предназначены для административных функций.
7. **Мониторинг**: Используйте эндпоинты `/api/health/*` для проверки состояния системы.
---
## 🔄 Миграция с старого API
Если у вас был код, использующий старый `ParserController`, вот соответствие эндпоинтов:
| Старый эндпоинт | Новый эндпоинт |
| ---------------------------------- | ----------------------------------------- |
| `POST /api/parser/parse/kursiv` | `POST /api/admin/parsers/parse/kursiv` |
| `POST /api/parser/parse/kapital` | `POST /api/admin/parsers/parse/kapital` |
| `POST /api/parser/parse/lsm` | `POST /api/admin/parsers/parse/lsm` |
| `POST /api/parser/parse/rbc` | `POST /api/admin/parsers/parse/rbc` |
| `POST /api/parser/parse/vedomosti` | `POST /api/admin/parsers/parse/vedomosti` |
| `POST /api/parser/parse/all` | `POST /api/admin/parsers/parse/all` |
| `GET /api/parser/items` | `GET /api/items` |
| `GET /api/parser/stats` | `GET /api/items/stats` |
| `GET /api/parser/health` | `GET /api/health` |
| `GET /api/parser/health/mongodb` | `GET /api/health/mongodb` |
| `GET /api/parser/scheduler/info` | `GET /api/health/scheduler` |