parser
This commit is contained in:
+507
-192
@@ -1,52 +1,53 @@
|
||||
# Руководство по API для фронтенда
|
||||
|
||||
## Обзор
|
||||
## Обзор изменений
|
||||
|
||||
После рефакторинга ParserController теперь поддерживает эффективную работу с фронтендом через строго типизированные DTO и расширенные возможности фильтрации и пагинации.
|
||||
После рефакторинга старый `ParserController` был разделен на три специализированных контроллера для лучшей организации и масштабируемости:
|
||||
|
||||
## Основные изменения
|
||||
- **`MarketItemController`** (`/api/items`) - для получения данных
|
||||
- **`ParserAdminController`** (`/api/admin/parsers`) - для управления парсерами
|
||||
- **`HealthCheckController`** (`/api/health`) - для мониторинга системы
|
||||
|
||||
### 1. Строгая типизация ответов
|
||||
---
|
||||
|
||||
Все ответы API теперь используют DTO классы вместо `Map<String, Object>`:
|
||||
## 📊 MarketItemController - Получение данных
|
||||
|
||||
- `ApiResponse<T>` - универсальный wrapper для всех ответов
|
||||
- `ParserResultDto` - результат парсинга
|
||||
- `ParserStatsDto` - статистика системы
|
||||
- `HealthCheckDto` - состояние сервиса
|
||||
**Базовый URL**: `/api/items`
|
||||
|
||||
### 2. Пагинация и сортировка
|
||||
|
||||
Поддержка Spring Data пагинации с параметрами:
|
||||
|
||||
- `page` - номер страницы (начиная с 0)
|
||||
- `size` - количество элементов на странице
|
||||
- `sort` - поле для сортировки и направление
|
||||
|
||||
### 3. Фильтрация данных
|
||||
|
||||
Возможность фильтрации по:
|
||||
|
||||
- `sourceName` - источнику новостей
|
||||
- `startDate` - начальной дате
|
||||
- `endDate` - конечной дате
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### 1. Получение записей с фильтрацией и пагинацией
|
||||
### 1. Получение списка новостей с фильтрацией и пагинацией
|
||||
|
||||
```http
|
||||
GET /api/parser/items?page=0&size=10&sort=publishedAt,desc&sourceName=Kursiv&startDate=2025-01-01&endDate=2025-01-31
|
||||
GET /api/items
|
||||
```
|
||||
|
||||
**Параметры:**
|
||||
**Параметры запроса:**
|
||||
|
||||
- `page` (optional, default: 0) - номер страницы
|
||||
- `size` (optional, default: 20) - размер страницы
|
||||
- `sort` (optional, default: "publishedAt,desc") - сортировка
|
||||
- `sourceName` (optional) - фильтр по источнику
|
||||
- `startDate` (optional) - начальная дата (ISO format)
|
||||
- `endDate` (optional) - конечная дата (ISO format)
|
||||
- `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');
|
||||
```
|
||||
|
||||
**Ответ:**
|
||||
|
||||
@@ -57,14 +58,14 @@ GET /api/parser/items?page=0&size=10&sort=publishedAt,desc&sourceName=Kursiv&sta
|
||||
"data": {
|
||||
"content": [
|
||||
{
|
||||
"id": "...",
|
||||
"sourceName": "Kursiv (Бизнес/экономика)",
|
||||
"id": "64f1a2b3c4d5e6f7g8h9i0j1",
|
||||
"sourceName": "Kursiv Media",
|
||||
"url": "https://kursiv.media/news/example",
|
||||
"title": "Заголовок новости",
|
||||
"url": "https://kursiv.media/...",
|
||||
"publishedAt": "2025-01-14T10:30:00",
|
||||
"addedAt": "2025-01-14T12:00:00",
|
||||
"rawText": "Текст статьи...",
|
||||
"hash": "...",
|
||||
"publishedAt": "2024-01-15T10:30:00",
|
||||
"addedAt": "2024-01-15T10:35:00",
|
||||
"rawText": "Текст новости без HTML тегов",
|
||||
"hash": "abc123def456...",
|
||||
"category": "Бизнес",
|
||||
"analytics": {
|
||||
"summary": null,
|
||||
@@ -77,36 +78,51 @@ GET /api/parser/items?page=0&size=10&sort=publishedAt,desc&sourceName=Kursiv&sta
|
||||
"pageable": {
|
||||
"sort": {
|
||||
"sorted": true,
|
||||
"unsorted": false,
|
||||
"empty": false
|
||||
"unsorted": false
|
||||
},
|
||||
"pageNumber": 0,
|
||||
"pageSize": 10,
|
||||
"pageSize": 20,
|
||||
"offset": 0,
|
||||
"paged": true,
|
||||
"unpaged": false
|
||||
},
|
||||
"totalElements": 25,
|
||||
"totalPages": 3,
|
||||
"totalElements": 150,
|
||||
"totalPages": 8,
|
||||
"last": false,
|
||||
"first": true,
|
||||
"numberOfElements": 10,
|
||||
"size": 10,
|
||||
"numberOfElements": 20,
|
||||
"size": 20,
|
||||
"number": 0,
|
||||
"sort": {
|
||||
"sorted": true,
|
||||
"unsorted": false,
|
||||
"empty": false
|
||||
},
|
||||
"empty": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Статистика системы
|
||||
### 2. Получение новости по ID
|
||||
|
||||
```http
|
||||
GET /api/parser/stats
|
||||
GET /api/items/{id}
|
||||
```
|
||||
|
||||
**Пример:**
|
||||
|
||||
```javascript
|
||||
fetch('/api/items/64f1a2b3c4d5e6f7g8h9i0j1');
|
||||
```
|
||||
|
||||
**Ответ:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"message": "Функция поиска по ID пока не реализована"
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Получение статистики
|
||||
|
||||
```http
|
||||
GET /api/items/stats
|
||||
```
|
||||
|
||||
**Ответ:**
|
||||
@@ -116,22 +132,23 @@ GET /api/parser/stats
|
||||
"success": true,
|
||||
"message": "Статистика получена успешно",
|
||||
"data": {
|
||||
"totalItems": 150,
|
||||
"totalItems": 1250,
|
||||
"sourceStatistics": {
|
||||
"Kursiv (Бизнес/экономика)": 75,
|
||||
"Kapital.kz (Бизнес)": 75
|
||||
"Kursiv Media": 300,
|
||||
"Kapital.kz": 250,
|
||||
"LSM.kz": 200,
|
||||
"РБК": 300,
|
||||
"Ведомости": 200
|
||||
},
|
||||
"lastUpdate": "2025-01-14T12:00:00"
|
||||
"lastUpdate": "2024-01-15T10:35:00"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Запуск парсинга
|
||||
|
||||
#### Парсинг всех источников
|
||||
### 4. Получение списка источников
|
||||
|
||||
```http
|
||||
POST /api/parser/parse/all
|
||||
GET /api/items/sources
|
||||
```
|
||||
|
||||
**Ответ:**
|
||||
@@ -139,37 +156,200 @@ POST /api/parser/parse/all
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "Парсинг всех источников завершен успешно",
|
||||
"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": 15,
|
||||
"totalItemsInDb": 90,
|
||||
"source": "kursiv",
|
||||
"processedItems": 12,
|
||||
"totalItemsInDb": 1277,
|
||||
"status": "completed"
|
||||
},
|
||||
{
|
||||
"source": "Kapital",
|
||||
"processedItems": 12,
|
||||
"totalItemsInDb": 90,
|
||||
"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
|
||||
POST /api/parser/parse/kursiv
|
||||
POST /api/parser/parse/kapital
|
||||
GET /api/admin/parsers
|
||||
```
|
||||
|
||||
### 4. Проверка состояния
|
||||
**Ответ:**
|
||||
|
||||
#### Общее состояние
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "Список парсеров получен",
|
||||
"data": ["kapital", "kursiv", "lsm", "rbc", "vedomosti"]
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Получение информации о парсерах
|
||||
|
||||
```http
|
||||
GET /api/parser/health
|
||||
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
|
||||
```
|
||||
|
||||
**Ответ:**
|
||||
@@ -181,19 +361,19 @@ GET /api/parser/health
|
||||
"data": {
|
||||
"status": "UP",
|
||||
"service": "RSS Parser System",
|
||||
"timestamp": 1705123456789,
|
||||
"scheduler": "Enabled - runs every 30 minutes"
|
||||
"timestamp": 1705312500000,
|
||||
"details": "Enabled - runs every 30 minutes"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Состояние MongoDB
|
||||
### 2. Проверка подключения к MongoDB
|
||||
|
||||
```http
|
||||
GET /api/parser/health/mongodb
|
||||
GET /api/health/mongodb
|
||||
```
|
||||
|
||||
**Ответ при успехе:**
|
||||
**Ответ (успех):**
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -201,13 +381,14 @@ GET /api/parser/health/mongodb
|
||||
"message": "MongoDB подключение успешно",
|
||||
"data": {
|
||||
"status": "UP",
|
||||
"message": "MongoDB подключение успешно",
|
||||
"timestamp": 1705123456789
|
||||
"service": "MongoDB подключение успешно",
|
||||
"timestamp": 1705312500000,
|
||||
"details": "Всего записей: 1317"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Ответ при ошибке:**
|
||||
**Ответ (ошибка):**
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -215,126 +396,260 @@ GET /api/parser/health/mongodb
|
||||
"message": "Ошибка подключения к MongoDB",
|
||||
"data": {
|
||||
"status": "DOWN",
|
||||
"message": "Ошибка подключения к MongoDB: Command failed with error 13 (Unauthorized)",
|
||||
"timestamp": 1705123456789,
|
||||
"service": "Ошибка подключения к MongoDB: Connection refused",
|
||||
"timestamp": 1705312500000,
|
||||
"suggestion": "Проверьте учетные данные в application.properties"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Примеры использования
|
||||
### 3. Информация о планировщике
|
||||
|
||||
### 1. Получение последних новостей с пагинацией
|
||||
|
||||
```javascript
|
||||
// Получить первую страницу с 10 записями, отсортированными по дате публикации
|
||||
fetch('/api/parser/items?page=0&size=10&sort=publishedAt,desc')
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
if (data.success) {
|
||||
const items = data.data.content;
|
||||
const totalPages = data.data.totalPages;
|
||||
// Обработка данных
|
||||
}
|
||||
});
|
||||
```http
|
||||
GET /api/health/scheduler
|
||||
```
|
||||
|
||||
### 2. Фильтрация по источнику
|
||||
|
||||
```javascript
|
||||
// Получить только новости от Kursiv
|
||||
fetch('/api/parser/items?sourceName=Kursiv (Бизнес/экономика)&page=0&size=20')
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
if (data.success) {
|
||||
const kursivNews = data.data.content;
|
||||
// Обработка данных
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### 3. Фильтрация по датам
|
||||
|
||||
```javascript
|
||||
// Получить новости за последнюю неделю
|
||||
const endDate = new Date().toISOString();
|
||||
const startDate = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString();
|
||||
|
||||
fetch(`/api/parser/items?startDate=${startDate}&endDate=${endDate}`)
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
if (data.success) {
|
||||
const recentNews = data.data.content;
|
||||
// Обработка данных
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### 4. Комплексная фильтрация
|
||||
|
||||
```javascript
|
||||
// Получить новости Kapital за последний месяц, отсортированные по дате
|
||||
const endDate = new Date().toISOString();
|
||||
const startDate = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString();
|
||||
|
||||
fetch(
|
||||
`/api/parser/items?sourceName=Kapital.kz (Бизнес)&startDate=${startDate}&endDate=${endDate}&sort=publishedAt,desc&page=0&size=50`
|
||||
)
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
if (data.success) {
|
||||
const kapitalNews = data.data.content;
|
||||
const totalCount = data.data.totalElements;
|
||||
// Обработка данных
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### 5. Получение статистики
|
||||
|
||||
```javascript
|
||||
fetch('/api/parser/stats')
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
if (data.success) {
|
||||
const stats = data.data;
|
||||
console.log(`Всего новостей: ${stats.totalItems}`);
|
||||
console.log('По источникам:', stats.sourceStatistics);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## Поддерживаемые форматы дат
|
||||
|
||||
API поддерживает следующие форматы дат:
|
||||
|
||||
- `yyyy-MM-dd` (например: 2025-01-14)
|
||||
- `yyyy-MM-dd'T'HH:mm:ss` (например: 2025-01-14T10:30:00)
|
||||
- `yyyy-MM-dd'T'HH:mm:ss.SSS` (например: 2025-01-14T10:30:00.000)
|
||||
- `yyyy-MM-dd HH:mm:ss` (например: 2025-01-14 10:30:00)
|
||||
|
||||
## Обработка ошибок
|
||||
|
||||
Все ответы API следуют единому формату:
|
||||
**Ответ:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"message": "Описание ошибки",
|
||||
"error": "Детальная информация об ошибке"
|
||||
"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", "РБК", "Ведомости"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
HTTP статус коды:
|
||||
### 4. Общая информация о системе
|
||||
|
||||
- `200` - Успешный запрос
|
||||
- `500` - Внутренняя ошибка сервера
|
||||
- `503` - Сервис недоступен (например, MongoDB)
|
||||
```http
|
||||
GET /api/health/system
|
||||
```
|
||||
|
||||
## Рекомендации для фронтенда
|
||||
**Ответ:**
|
||||
|
||||
1. **Кэширование**: Используйте кэширование для статистики и часто запрашиваемых данных
|
||||
2. **Пагинация**: Реализуйте бесконечную прокрутку или традиционную пагинацию
|
||||
3. **Фильтры**: Предоставьте пользователю удобные фильтры по источнику и датам
|
||||
4. **Обновление**: Используйте WebSocket или polling для обновления данных в реальном времени
|
||||
5. **Обработка ошибок**: Всегда проверяйте поле `success` в ответе
|
||||
```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` |
|
||||
|
||||
Reference in New Issue
Block a user