Введение
Этот документ описывает синтаксис для выполнения запросов к нашему API, позволяя вам динамически фильтровать, сортировать, группировать и пагинировать данные. Используйте навигацию слева для изучения различных возможностей.
Базовая структура URL
Запросы отправляются на эндпоинты вида:
- `http://myapi.org/api/list/{resource_name}` - получить список записей
- `http://myapi.org/api/read/{resource_name}/{id}` - получить одну запись
- `http://myapi.org/api/create/{resource_name}` - создать запись
- `http://myapi.org/api/update/{resource_name}/{id}` - обновить запись
- `http://myapi.org/api/delete/{resource_name}/{id}` - удалить запись
- `http://myapi.org/api/save/{resource_name}` - создать или обновить запись
Поддержка GET и POST
API поддерживает как GET, так и POST запросы. Для сложных запросов рекомендуется использовать POST с JSON телом.
Использование API в PHP коде
Класс Api предоставляет удобные методы для работы с базой данных напрямую из PHP кода, без необходимости делать HTTP запросы.
Инициализация API
Создайте экземпляр класса Api для работы с базой данных:
<?php
require_once __DIR__ . '/api/api.php';
$api = new Api();
// API автоматически загружает настройки из api.json
// и подключает драйвер базы данных, указанный в конфигурации
?>💡 Важно!
- • Драйвер подключается автоматически на основе настройки
driverвapi.json - • Поддерживается динамическое подключение драйверов (mysql, postgresql и т.д.)
- • Драйвер инициализируется при первом использовании (lazy loading)
CRUD методы
Класс Api предоставляет следующие методы для работы с данными:
📋 list() - Получить список записей
<?php
$api = new Api();
// Простой список
$users = $api->list([
'@table' => 'users',
'status' => 'active',
'@limit' => 10
]);
// С фильтрацией и сортировкой
$orders = $api->list([
'@table' => 'orders',
'status' => 'pending',
'@order' => 'created_at:desc',
'@page' => 1,
'@size' => 20
]);
// С JOIN
$ordersWithUsers = $api->list([
'@table' => 'orders',
'@join' => ['left:users[orders.user_id=users.id]'],
'@select' => 'orders.id,orders.total,users.name:customer_name',
'@order' => 'orders.created_at:desc'
]);
?>👁️ read() - Получить одну запись
<?php
$api = new Api();
// По ID
$user = $api->read([
'@table' => 'users',
'id' => 'user123'
]);
// С дополнительными полями
$user = $api->read([
'@table' => 'users',
'id' => 'user123',
'@select' => 'id,name,email,profile.avatar,settings.theme'
]);
// Если id не указан, используется из маршрута (если доступен)
$api->route = ['item' => 'user123', 'table' => 'users'];
$user = $api->read();
?>➕ create() - Создать запись
<?php
$api = new Api();
// Создание с простыми полями
$newUser = $api->create([
'@table' => 'users',
'@set' => [
'name' => 'Иван Иванов',
'email' => 'ivan@example.com',
'status' => 'active'
],
'@return' => 'id,name,email,created_at'
]);
// Создание с вложенными JSON полями
$newUser = $api->create([
'@table' => 'users',
'@set' => [
'name' => 'Иван Иванов',
'email' => 'ivan@example.com',
'profile.avatar' => 'https://example.com/avatar.jpg',
'profile.bio' => 'Разработчик',
'settings.theme' => 'dark',
'settings.notifications.email' => true
],
'@return' => 'id,name,email,profile,settings'
]);
?>✏️ update() - Обновить запись
<?php
$api = new Api();
// Обновление по ID
$result = $api->update([
'@table' => 'users',
'id' => 'user123',
'@set' => [
'status' => 'inactive',
'last_login' => date('Y-m-d H:i:s')
],
'@return' => 'id,name,status,last_login'
]);
// Массовое обновление с условиями
$result = $api->update([
'@table' => 'users',
'last_login(lt)' => '2024-01-01',
'status' => 'active',
'@set' => [
'status' => 'inactive',
'deactivated_at' => date('Y-m-d H:i:s')
]
]);
// Обновление JSON полей
$result = $api->update([
'@table' => 'users',
'id' => 'user123',
'@set' => [
'profile.avatar.url' => 'https://new-avatar.jpg',
'profile.bio' => 'Новая биография',
'settings.theme' => 'light'
]
]);
?>🗑️ delete() - Удалить запись
<?php
$api = new Api();
// Удаление по ID
$result = $api->delete([
'@table' => 'users',
'id' => 'user123'
]);
// Массовое удаление с условиями
$result = $api->delete([
'@table' => 'users',
'status' => 'inactive',
'last_login(lt)' => '2020-01-01'
]);
// Удаление с возвратом удаленных записей
$result = $api->delete([
'@table' => 'users',
'id' => 'user123',
'@return' => 'id,name,email'
]);
?>💾 save() - Создать или обновить
<?php
$api = new Api();
// Если запись с таким ID существует - обновит, иначе создаст
$result = $api->save([
'@table' => 'users',
'@set' => [
'id' => 'user123',
'name' => 'Иван Иванов',
'email' => 'ivan@example.com',
'status' => 'active'
],
'@return' => 'id,name,email,created_at,updated_at'
]);
// Без ID - всегда создаст новую запись
$result = $api->save([
'@table' => 'users',
'@set' => [
'name' => 'Новый пользователь',
'email' => 'new@example.com'
]
]);
?>Метод save() автоматически определяет, нужно ли создавать новую запись или обновлять существующую на основе наличия ID и его существования в базе данных.
Логические операции (OR и AND)
Вы можете объединять несколько условий с помощью операторов @or и @and для создания сложных запросов.
🔀 Использование @or (ИЛИ)
Оператор @or позволяет найти записи, которые соответствуют хотя бы одному из условий.
<?php
$api = new Api();
// Найти пользователей со статусом "active" ИЛИ ролью "admin"
$users = $api->list([
'@table' => 'users',
'@or' => [
['status' => 'active'],
['role' => 'admin']
]
]);
// Более сложный пример: активные пользователи ИЛИ администраторы ИЛИ модераторы
$users = $api->list([
'@table' => 'users',
'@or' => [
['status' => 'active'],
['role' => 'admin'],
['role' => 'moderator']
],
'@order' => 'created_at:desc'
]);
// Комбинация с другими условиями
$users = $api->list([
'@table' => 'users',
'department' => 'IT', // Всегда должно быть выполнено
'@or' => [
['status' => 'active'],
['role' => 'admin']
]
]);
?>🔗 Использование @and (И)
Оператор @and позволяет явно указать, что все условия должны быть выполнены одновременно.
<?php
$api = new Api();
// Найти пользователей со статусом "active" И возрастом больше 18
$users = $api->list([
'@table' => 'users',
'@and' => [
['status' => 'active'],
['age(gt)' => 18]
]
]);
// Несколько условий с разными операторами
$users = $api->list([
'@table' => 'users',
'@and' => [
['status' => 'active'],
['age(gte)' => 18],
['age(lte)' => 65],
['city(in)' => ['Moscow', 'SPB']]
]
]);
?>🔀🔗 Комбинирование @or и @and
Вы можете создавать сложные вложенные структуры, комбинируя @or и @and.
<?php
$api = new Api();
// Найти пользователей, которые:
// (статус = "active" ИЛИ роль = "admin") И отдел = "IT"
$users = $api->list([
'@table' => 'users',
'@and' => [
[
'@or' => [
['status' => 'active'],
['role' => 'admin']
]
],
['department' => 'IT']
]
]);
// Более сложный пример:
// (статус = "active" ИЛИ роль = "admin")
// И
// (возраст >= 18 И возраст <= 65)
$users = $api->list([
'@table' => 'users',
'@and' => [
[
'@or' => [
['status' => 'active'],
['role' => 'admin']
]
],
[
'@and' => [
['age(gte)' => 18],
['age(lte)' => 65]
]
]
]
]);
// Использование в update() с условиями
$result = $api->update([
'@table' => 'users',
'@and' => [
[
'@or' => [
['status' => 'active'],
['status' => 'pending']
]
],
['last_login(lt)' => '2024-01-01']
],
'@set' => [
'status' => 'inactive',
'deactivated_at' => date('Y-m-d H:i:s')
]
]);
// Использование в delete() с условиями
$result = $api->delete([
'@table' => 'users',
'@or' => [
['status' => 'deleted'],
['last_login(lt)' => '2020-01-01']
]
]);
?>💡 Важные моменты:
- • По умолчанию все условия объединяются через
AND, если не указан@or - •
@andполезен для явного указания логики, особенно при комбинации с@or - • Можно создавать многоуровневые вложенные структуры
- • Логические операторы работают во всех CRUD методах:
list(),read(),update(),delete()
Работа с драйверами
API поддерживает динамическое подключение различных драйверов баз данных:
Конфигурация драйвера в api.json:
{
"driver": "mysql",
"drivers": {
"mysql": {
"host": "localhost",
"port": 3306,
"database": "mydb",
"username": "user",
"password": "pass"
},
"postgresql": {
"host": "localhost",
"port": 5432,
"database": "mydb",
"username": "user",
"password": "pass"
}
}
}💡 Как это работает:
- • Драйвер определяется из настройки
"driver"вapi.json - • Файл драйвера загружается автоматически:
drivers/{driver}.php - • Класс драйвера ищется в форматах:
MysqlDriver,mysqlDriver - • Драйвер инициализируется при первом вызове CRUD метода (lazy loading)
- • Экземпляр драйвера кэшируется для повторного использования
Практические примеры
Пример 1: Получение данных с фильтрацией
<?php
$api = new Api();
// Получить активных пользователей за последний месяц
$activeUsers = $api->list([
'@table' => 'users',
'status' => 'active',
'created_at(gte)' => date('Y-m-01'),
'@order' => 'created_at:desc',
'@page' => 1,
'@size' => 50
]);
foreach ($activeUsers as $user) {
echo $user['name'] . " - " . $user['email'] . "\n";
}
?>Пример 2: Создание записи с валидацией
<?php
$api = new Api();
// Проверить, существует ли пользователь
$existingUser = $api->read([
'@table' => 'users',
'email' => 'ivan@example.com'
]);
if (!$existingUser) {
// Создать нового пользователя
$newUser = $api->create([
'@table' => 'users',
'@set' => [
'name' => 'Иван Иванов',
'email' => 'ivan@example.com',
'status' => 'active'
]
]);
echo "Пользователь создан: " . $newUser['id'];
} else {
echo "Пользователь уже существует";
}
?>Пример 3: Использование save() для upsert
<?php
$api = new Api();
// Автоматически создаст или обновит запись
$result = $api->save([
'@table' => 'users',
'@set' => [
'id' => 'user123',
'name' => 'Иван Иванов',
'email' => 'ivan@example.com',
'last_seen' => date('Y-m-d H:i:s')
]
]);
// Не нужно проверять существование - save() сделает это сам
?>Пример 4: Работа с JOIN
<?php
$api = new Api();
// Получить заказы с информацией о пользователях
$orders = $api->list([
'@table' => 'orders',
'@join' => ['left:users[orders.user_id=users.id]'],
'@select' => 'orders.id,orders.total,orders.created_at,users.name:customer_name,users.email:customer_email',
'orders.status' => 'completed',
'@order' => 'orders.created_at:desc',
'@page' => 1,
'@size' => 20
]);
foreach ($orders as $order) {
echo "Заказ #{$order['id']} от {$order['customer_name']} на сумму {$order['total']}\n";
}
?>Пример 5: Массовые операции
<?php
$api = new Api();
// Обновить статус всех неактивных пользователей
$result = $api->update([
'@table' => 'users',
'status' => 'active',
'last_login(lt)' => '2024-01-01',
'@set' => [
'status' => 'inactive',
'deactivated_at' => date('Y-m-d H:i:s')
]
]);
echo "Обновлено записей: " . ($result['affected'] ?? 0);
// Удалить старые записи
$result = $api->delete([
'@table' => 'logs',
'created_at(lt)' => date('Y-m-d', strtotime('-1 year'))
]);
echo "Удалено записей: " . ($result['affected'] ?? 0);
?>Преимущества использования PHP методов
- ✅ Нет HTTP overhead - прямые вызовы методов без сетевых запросов
- ✅ Типобезопасность - IDE подсказки и проверка типов
- ✅ Производительность - быстрее чем HTTP запросы
- ✅ Удобство отладки - можно использовать отладчик PHP
- ✅ Единый код - один и тот же API для HTTP и PHP вызовов
- ✅ Автоматический парсинг - запросы парсятся автоматически
- ✅ Динамические драйверы - легко переключаться между БД
Быстрый старт
Пошаговое руководство по подключению API к вашему проекту.
Шаг 1: Установка API
- Скопируйте папку
api/в корень вашего проекта - Убедитесь, что веб-сервер имеет доступ к файлам API
- Проверьте права на запись для файла
api.json(хранит настройки)
Структура файлов:
project/
├── api/
│ ├── api.php # Точка входа
│ ├── api_parser.php # Парсер запросов
│ ├── drivers/
│ │ └── mysql.php # MySQL драйвер
│ ├── api_router.php # Роутер
│ ├── api_settings.php # Веб-интерфейс настроек
│ ├── api_help.php # Эта документация
│ ├── api.ini # Маршруты
│ └── api.json # Настройки (создастся автоматически)
└── index.php # Ваше приложениеШаг 2: Подключение в вашем проекте
Добавьте следующий код в самое начало вашего основного файла (например, index.php):
require_once __DIR__ . '/api/api.php';
$api = new Api();
$api->run();
// Далее сод вашего приложения
💡 Важно!
- • Код должен быть добавлен в самом начале файла, до любого вывода HTML
- • API обрабатывает только запросы к
/api/* - • Если запрос не к API, выполнение продолжается дальше в вашем коде
- • Не нужен закрывающий тег
?>в конце файла
Шаг 3: Настройка через веб-интерфейс
- Откройте в браузере:
http://ваш-сайт.com/api/settings - При первом входе введите пароль для доступа к панели управления
- Настройте подключение к базе данных (MySQL):
- Host (обычно
localhost) - Username (пользователь БД)
- Password (пароль БД)
- Database (имя базы данных)
- Port (обычно
3306)
- Host (обычно
- Нажмите кнопку "Save Settings"
Шаг 4: Первый запрос
Проверьте работу API, выполнив простой запрос:
GET http://ваш-сайт.com/api/list/users?@limit=10Или используйте cURL:
curl http://ваш-сайт.com/api/list/users?@limit=10🔒 Если API защищен токеном:
curl -H "Authorization: Bearer YOUR_TOKEN" \
http://ваш-сайт.com/api/list/users?@limit=10✅ Готово!
Теперь ваш API полностью настроен и готов к использованию. Перейдите к разделу "Управление токенами" для настройки безопасности.
Аутентификация
Для доступа к защищенным ресурсам API требуется передать токен аутентификации. Это можно сделать двумя способами:
1. Bearer Token (рекомендуется)
Передайте токен в заголовке Authorization:
Authorization: Bearer YOUR_SECRET_TOKEN2. Параметр @token
Передайте токен как параметр запроса:
@token=YOUR_SECRET_TOKENПримечание
Bearer Token имеет приоритет над параметром @token.
Управление токенами
Токены обеспечивают безопасный доступ к API и позволяют гибко управлять правами доступа.
Создание токена через веб-интерфейс
-
Откройте панель управления:
http://ваш-сайт.com/api/settings - Перейдите в раздел "Tokens" в боковом меню
-
Включите защиту API (переключатель "Protect API access")
Если защита отключена, API будет доступен без токена
- Нажмите "+ Add Token" для создания нового токена
-
Заполните параметры токена:
- Token name - имя для идентификации токена (например, "Mobile App", "Frontend")
- Token - сам токен (нажмите 🔄 для автогенерации)
- Tables - список таблиц, к которым разрешен доступ (оставьте пустым для доступа ко всем)
- Permissions - отметьте нужные разрешения:
- C - Create (создание записей)
- R - Read (чтение записей)
- U - Update (обновление записей)
- D - Delete (удаление записей)
- S - Save (создание или обновление)
- L - List (получение списков)
- Нажмите "Save Settings" для сохранения изменений
💡 Пример настройки токена:
Имя: "Mobile App Token"
Токен: "abc123xyz456def789..." (50 символов)
Таблицы: users, orders, products
Разрешения: R, L (только чтение и список)
Получение токена программно
Вы можете получить токен из настроек API в вашем PHP коде:
<?php
require_once __DIR__ . '/api/api.php';
$api = new Api();
// Получить токен по имени
$token = $api->getToken('Mobile App Token');
if ($token) {
echo "Token: " . $token['value'] . "\n";
echo "Access: " . implode(', ', $token['access']) . "\n";
} else {
echo "Token not found\n";
}
?>Результат:
Token: abc123xyz456def789...
Access: r, lИспользование токена в запросах
Метод 1: Bearer Token (рекомендуется)
curl -H "Authorization: Bearer YOUR_SECRET_TOKEN" \
http://ваш-сайт.com/api/list/usersМетод 2: Параметр @token
GET http://ваш-сайт.com/api/list/users?@token=YOUR_SECRET_TOKENМетод 3: В теле POST запроса
POST http://ваш-сайт.com/api/list/users
Content-Type: application/json
{
"@token": "YOUR_SECRET_TOKEN",
"status": "active"
}Ограничение доступа к таблицам
Токены можно ограничить конкретными таблицами для повышения безопасности:
✅ Токен с доступом к users
GET /api/list/users
→ ✅ Разрешено❌ Токен без доступа к orders
GET /api/list/orders
→ ❌ 403 Access denied⚠️ Важно:
Если список таблиц пуст, токен имеет доступ ко ВСЕМ таблицам (с учетом разрешений C/R/U/D/S/L).
Примеры разрешений токенов
📱 Мобильное приложение
Разрешения: R, L (только чтение)
Таблицы: users, products, categories
🖥️ Панель администратора
Разрешения: C, R, U, D, S, L (полный доступ)
Таблицы: все (список пуст)
📊 Сервис аналитики
Разрешения: L (только списки)
Таблицы: orders, analytics
⚙️ Внешняя интеграция
Разрешения: C, U, S (создание и обновление)
Таблицы: webhooks, sync_log
🔐 Безопасность токенов
- Храните токены в безопасном месте (переменные окружения, защищенные конфиги)
- Никогда не передавайте токены в URL на production (используйте Bearer Token)
- Регулярно меняйте токены для критичных систем
- Используйте разные токены для разных приложений
- Настраивайте минимальные необходимые разрешения (принцип наименьших привилегий)
Действия (CRUD операции)
API поддерживает полный набор CRUD операций для работы с данными.
LIST - Получение списка
Получить список записей с фильтрацией, сортировкой и пагинацией.
GET /api/list/users?status=active&@page=1&@size=10READ - Чтение одной записи
Получить одну запись по ID.
GET /api/read/users/user123CREATE - Создание записи
Создать новую запись. Данные передаются через параметр @set или в теле POST запроса.
Способ 1: POST запрос с JSON телом
POST /api/create/users
Content-Type: application/json
{
"@set": {
"name": "Иван Иванов",
"email": "ivan@example.com",
"role": "user"
},
"@return": "id,name,email,created_at"
}Способ 2: GET запрос с параметром @set
Для быстрого создания можно использовать GET запрос:
GET /api/create/users?@set=name=Иван%20Иванов&email=ivan@example.com&role=user&@return=id,name,email,created_atСпособ 3: GET с @set в квадратных скобках
Более читаемый вариант с использованием квадратных скобок:
GET /api/create/users?@set=[name=John%20Doe&email=john@example.com&role=admin]&@return=id,name,emailСоздание с вложенными JSON полями через GET
GET /api/create/users?@set=name=John&email=john@test.com&profile.avatar=https://example.com/pic.jpg&profile.bio=Developer&settings.theme=dark&@return=id,name,profile,settingsТо же самое с использованием квадратных скобок:
GET /api/create/users?@set=[name=John&email=john@test.com&profile.avatar=https://example.com/pic.jpg&profile.bio=Developer&settings.theme=dark]&@return=id,name,profile,settings💡 Параметр @return указывает, какие поля вернуть после создания.
UPDATE - Обновление записи
Обновить существующую запись. Можно обновлять по ID или по условию.
Способ 1: POST запрос с JSON телом
POST /api/update/users/user123
{
"@set": {
"status": "inactive",
"updated_at": "2025-11-11"
},
"@return": "id,name,status"
}Способ 2: GET запрос с множественными @set
Для простых обновлений можно использовать GET запрос:
GET /api/update/users/user123?@set=status=inactive&@set=last_login=2025-11-11&@return=id,name,statusСпособ 3: GET запрос с объединенным @set
Можно передать несколько полей в одном параметре @set, разделяя их через &:
GET /api/update/users/user123?@set=status=inactive&updated_at=2025-11-11&@return=id,name,statusСпособ 4: GET запрос с @set в квадратных скобках (рекомендуется)
Квадратные скобки улучшают читаемость и чётко отделяют параметры @set от других:
GET /api/update/users/user123?@set=[status=inactive&updated_at=2025-11-11]&@return=id,name,statusПример с токенами (ваш случай):
GET /api/update/users/user123?@set=[firebaseToken=abc123&mobileFirebaseToken=xyz789]&@return=id,firebaseToken,mobileFirebaseTokenОбновление JSON полей через GET
Используйте dot notation для вложенных полей:
GET /api/update/users/user123?@set=profile.avatar.url=https://new-avatar.jpg&profile.bio=Новая%20биография&@return=id,profileПримечание
Для массового обновления используйте условия без указания ID в URL. Для сложных обновлений рекомендуется использовать POST запросы.
DELETE - Удаление записи
Удалить запись по ID или по условию.
DELETE /api/delete/users/user123Для массового удаления используйте POST с условиями фильтрации.
SAVE - Создание или обновление
Автоматически создает запись, если ID не существует, или обновляет существующую.
POST /api/save/users
{
"@set": {
"id": "user123",
"name": "Обновленное имя"
}
}Параметр @set для CREATE/UPDATE
Параметр @set содержит данные для создания или обновления записи. Поддерживает dot notation для вложенных JSON полей: `profile.avatar.url`.
Синтаксис @set в GET запросах:
- Простой: `@set=field1=value1&field2=value2`
- В квадратных скобках: `@set=[field1=value1&field2=value2]`
- Множественный: `@set=field1=value1&@set=field2=value2`
- С dot notation: `@set=profile.name=John&profile.age=30`
- Dot notation в скобках: `@set=[profile.name=John&profile.age=30]`
- Комбинированный: `@set=name=John&profile.avatar=url&status=active`
💡 Квадратные скобки автоматически удаляются при парсинге. Используйте их для лучшей читаемости URL-запросов.
Синтаксис @set в POST запросах:
Условия
Вы можете фильтровать данные, указывая условия для отдельных полей. Условия можно передавать как в GET-запросах (через URL параметры), так и в POST-запросах (через JSON тело). Общий синтаксис: `field(operator)=value`. Если оператор не указан, по умолчанию используется `eq` (равно).
GET-запросы (URL параметры)
Условия передаются через URL параметры. Удобно для простых запросов и тестирования в браузере.
GET /api/users?status=active&age(gt)=18&name(like)=%john%POST-запросы (JSON тело)
Условия передаются в JSON теле запроса. Позволяет передавать сложные структуры данных.
{
"status": "active",
"age(gt)": 18,
"name(like)": "%john%"
}
Доступные операторы
| Оператор | Описание | GET пример | POST пример |
|---|---|---|---|
| `eq` (или нет) | Равно | status=active |
"status": "active" |
| `ne` | Не равно | status(ne)=archived |
"status(ne)": "archived" |
| `gt` | Больше | amount(gt)=100 |
"amount(gt)": 100 |
| `lt` | Меньше | price(lt)=50 |
"price(lt)": 50 |
| `gte` | Больше или равно | date(gte)=2025-01-01 |
"date(gte)": "2025-01-01" |
| `lte` | Меньше или равно | date(lte)=2025-12-31 |
"date(lte)": "2025-12-31" |
| `in` | Входит в список | role(in)=[admin,moderator] |
"role(in)": ["admin", "moderator"] |
| `not_in` | Не входит в список | category(not_in)=[spam,deleted] |
"category(not_in)": ["spam", "deleted"] |
| `between` | Между диапазоном | date(between)=[2025-07-01,2025-07-08] |
"date(between)": ["2025-07-01", "2025-07-08"] |
| `like` | Похож (сопоставление по шаблону) | name(like)=%book% |
"name(like)": "%book%" |
| `is_null` | Равен NULL | last_login(is_null)=true |
"last_login(is_null)": true |
| `not_null` | Не равен NULL | description(not_null)=true |
"description(not_null)": true |
| `empty` | Пустое значение (NULL, пустая строка, пустой массив) | email(empty)=true |
"email(empty)": true |
| `not_empty` | Не пустое значение | avatar(not_empty)=true |
"avatar(not_empty)": true |
| `not_between` | Не между диапазоном | date(not_between)=[2025-01-01,2025-06-30] |
"date(not_between)": ["2025-01-01", "2025-06-30"] |
| `not_like` | Не похож (исключение по шаблону) | name(not_like)=%test% |
"name(not_like)": "%test%" |
Полные примеры запросов
GET-запрос с несколькими условиями
Находит активных пользователей от 18 до 65 лет из Москвы или СПб, чьё имя содержит "john".
GET /api/users?status=active&age(gte)=18&age(lte)=65&city(in)=[Moscow,SPB]&name(like)=%john%POST-запрос с несколькими условиями
Тот же запрос, но через POST с JSON телом.
{
"status": "active",
"age(gte)": 18,
"age(lte)": 65,
"city(in)": ["Moscow", "SPB"],
"name(like)": "%john%"
}
Логические операции
Объединяйте несколько условий с помощью операторов `@and` и `@or`. Синтаксис отличается для GET и POST запросов для удобства.
GET-запросы (функциональная нотация)
Условия перечисляются через запятую внутри круглых скобок. Удобно для создания URL вручную.
http://.../users?@or=(status=active,role=admin)&department=ITPOST-запросы (JSON-массив)
Используется JSON-массив объектов, что позволяет создавать сложные вложенные структуры.
{
"@and": [
{
"@or": [
{"users.status": "active"},
{"users.role": "admin"}
]
},
{"users.department": "IT"}
]
}
Объединения (JOIN)
Параметр `@join` позволяет объединять данные из нескольких связанных таблиц в одном запросе, значительно упрощая работу с реляционными данными.
Базовый синтаксис
Параметр `@join` принимает массив строк, где каждая строка описывает одно присоединение:
Формат:
[тип]:[таблица][[условие_связи]]
Тип JOIN
inner, left, right, full
Таблица
Имя присоединяемой таблицы
Условие
Поля для связи таблиц
Простой пример:
@join=["left:users[orders.user_id=users.id]"]Присоединяет таблицу users к таблице orders по полю user_id
Типы JOIN
🔹 INNER JOIN (inner)
Возвращает только записи, для которых найдено совпадение в обеих таблицах.
@join=["inner:users[orders.user_id=users.id]"]Результат: Только заказы, у которых есть пользователь
🔹 LEFT JOIN (left)
Возвращает все записи из левой таблицы и совпадающие из правой. Если совпадений нет, поля правой таблицы будут NULL.
@join=["left:users[orders.user_id=users.id]"]Результат: Все заказы, даже если пользователь не найден (поля user будут NULL)
🔹 RIGHT JOIN (right)
Возвращает все записи из правой таблицы и совпадающие из левой.
@join=["right:users[orders.user_id=users.id]"]Результат: Все пользователи, даже без заказов
🔹 FULL JOIN (full)
Возвращает все записи из обеих таблиц, даже без совпадений.
@join=["full:users[orders.user_id=users.id]"]Результат: Все заказы и все пользователи
💡 Рекомендация:
Используйте LEFT JOIN в 90% случаев - это самый распространенный и безопасный тип объединения.
Множественные JOIN
Можно объединить несколько таблиц в одном запросе:
GET запрос:
GET /api/list/orders?@join=["left:users[orders.user_id=users.id]","inner:products[orders.product_id=products.id]"]&@select=orders.id,users.name:customer_name,products.name:product_namePOST запрос (рекомендуется для сложных JOIN):
POST /api/list/orders
Content-Type: application/json
{
"@join": [
"left:users[orders.user_id=users.id]",
"inner:products[orders.product_id=products.id]",
"left:categories[products.category_id=categories.id]"
],
"@select": "orders.id,users.name:customer,products.name:product,categories.name:category",
"@return": "id,customer,product,category,orders.total"
}Результат: Заказы с данными пользователя, продукта и категории в одном запросе
Практические примеры
📱 Пример 1: Заказы с пользователями
Получить все заказы со статусом "pending" и информацией о пользователях:
GET /api/list/orders?status=pending&@join=["left:users[orders.user_id=users.id]"]&@select=orders.*,users.name,users.email&@order=orders.created_at:desc🛒 Пример 2: Продукты с категориями и производителями
Каталог продуктов с полной информацией:
POST /api/list/products
{
"@join": [
"left:categories[products.category_id=categories.id]",
"left:manufacturers[products.manufacturer_id=manufacturers.id]"
],
"@select": "products.id,products.name,products.price,categories.name:category,manufacturers.name:brand",
"products.status": "active",
"@order": "products.price:asc",
"@page": 1,
"@size": 20
}👥 Пример 3: Пользователи с количеством заказов
Список пользователей с статистикой их заказов:
POST /api/list/users
{
"@join": [
"left:orders[users.id=orders.user_id]"
],
"@select": "users.id,users.name,users.email,@count(orders.id):orders_count,@sum(orders.total):total_spent",
"@group": "users.id,users.name,users.email",
"@order": "total_spent:desc",
"@having": "orders_count(gt)=0"
}📊 Пример 4: Сложный JOIN с фильтрацией
Заказы за последний месяц с детализацией:
POST /api/list/orders
{
"@join": [
"left:users[orders.user_id=users.id]",
"left:products[orders.product_id=products.id]",
"left:payments[orders.id=payments.order_id]"
],
"@select": "orders.id,orders.created_at,users.name:customer,users.email,products.name:product,orders.total,payments.status:payment_status",
"@and": [
{"orders.created_at(gte)": "2025-10-01"},
{"orders.status": "completed"}
],
"@order": "orders.created_at:desc",
"@page": 1,
"@size": 50
}Работа с полями из JOIN таблиц
Фильтрация по полям JOIN таблиц:
POST /api/list/orders
{
"@join": ["left:users[orders.user_id=users.id]"],
"users.email(like)": "%@gmail.com",
"users.status": "active",
"@select": "orders.*,users.name,users.email"
}Сортировка по полям JOIN таблиц:
@join=["left:users[orders.user_id=users.id]"]&@order=users.name:asc,orders.created_at:descГруппировка с JOIN:
POST /api/list/orders
{
"@join": ["left:products[orders.product_id=products.id]"],
"@group": "products.id,products.name",
"@select": "products.name:product,@count(orders.id):total_orders,@sum(orders.total):revenue",
"@order": "revenue:desc"
}Выбор полей при использовании JOIN
Выбрать все поля из основной таблицы:
@select=orders.*,users.name,users.emailВыбрать все поля из всех таблиц:
@select=orders.*,users.*,products.*⚠️ Не рекомендуется - возвращает много данных
Выбрать конкретные поля с псевдонимами:
@select=orders.id:order_id,orders.total,users.name:customer_name,users.email:customer_email,products.name:product_title✅ Рекомендуется - явное указание нужных полей
Если @select не указан:
API автоматически вернет все поля из всех таблиц (основной + все JOIN)
❌ Частые ошибки при работе с JOIN
1. Неправильный формат условия связи
❌ Неверно: @join=["left:users[user_id=id]"]
✅ Верно: @join=["left:users[orders.user_id=users.id]"]
Нужно указывать таблицу для каждого поля
2. Забыли указать @select
Без @select вернутся ВСЕ поля из всех таблиц, что может быть избыточно
3. Неправильный порядок JOIN
Порядок JOIN важен! Сначала присоединяйте таблицы первого уровня, потом второго
4. Дублирование имен полей
Если в разных таблицах есть поля с одинаковыми именами, используйте псевдонимы
✅ @select=orders.id:order_id,users.id:user_id
⚡ Советы по производительности
- ✅ Используйте
@selectдля выбора только нужных полей - ✅ Добавляйте индексы на поля, используемые в условиях JOIN
- ✅ Используйте фильтрацию для уменьшения количества данных до JOIN
- ✅ Предпочитайте INNER JOIN, если не нужны записи без совпадений
- ✅ Ограничивайте результаты с помощью
@limitили@page/@size - ⚠️ Избегайте JOIN более 4-5 таблиц в одном запросе
- ⚠️ Не используйте
table.*для всех JOIN таблиц одновременно
Фильтр полей
Используйте `@select` и `@return` для управления тем, какие поля возвращаются в ответе API. Параметр `@select` указывает, какие поля извлекать из базы данных (влияет на SQL запрос), а `@return` фильтрует уже полученные данные перед возвратом клиенту (постобработка).
Основной синтаксис
@select=id,name,email,created_atПсевдонимы полей
Используйте двоеточие для переименования полей:
@select=id,name:full_name,email:contact_emailПоля из JOIN таблиц
@select=orders.id,users.name:user_name,products.name:product_nameАгрегатные функции
Используйте @ перед именем функции:
@select=category,@count(id):total,@sum(amount):total_amount,@avg(price):avg_priceДоступные функции: @count, @sum, @avg, @min, @max
Выбор всех полей таблицы
@select=users.*,orders.id,orders.totalПримечание
Если @select не указан, возвращаются все поля из основной таблицы и всех JOIN таблиц.
Параметр @return
Параметр `@return` позволяет указать, какие поля должны быть возвращены после операций CREATE, UPDATE, DELETE и в запросах LIST. В отличие от `@select`, который влияет на SQL запрос, `@return` фильтрует уже полученные данные перед возвратом клиенту.
Использование в CREATE
POST /api/create/users
{
"@set": {
"name": "Иван Иванов",
"email": "ivan@example.com"
},
"@return": "id,name,email,created_at"
}API вернет только указанные поля созданной записи.
Использование в UPDATE
POST /api/update/users
{
"status": "active",
"@set": {
"last_login": "2025-11-11"
},
"@return": "id,name,status,last_login"
}Возвращает только указанные поля всех обновленных записей.
Использование в LIST
GET /api/list/users?status=active&@return=id,name,emailФормат значения
Поля перечисляются через запятую:
@return=id,name,email,profile.avatar,created_atРазница между @select и @return
- @select - указывает, какие поля извлекать из базы данных (влияет на SQL запрос)
- @return - фильтрует уже полученные данные перед возвратом клиенту (постобработка)
Рекомендация
Используйте @return для упрощения клиентского кода и снижения объема передаваемых данных.
Сортировка
Параметр `@order` (или `@sort`) упорядочивает результаты по одному или нескольким полям.
Простая сортировка
Сортировка по одному полю (по умолчанию по возрастанию):
@order=created_atУказание направления
Используйте `:asc` для возрастания или `:desc` для убывания:
@order=price:descМожно использовать короткие формы: `:d` вместо `:desc`
Множественная сортировка
Сортировка по нескольким полям через запятую:
@order=priority:desc,created_at:asc,nameЗаписи будут отсортированы сначала по приоритету (убывание), затем по дате создания (возрастание), затем по имени.
Сортировка JOIN полей
@order=users.created_at:desc,orders.total:descСортировка JSON полей
Используйте dot notation для JSON полей:
@order=profile.rating:desc,settings.priorityПримечание
Можно использовать как @order, так и @sort - оба параметра работают одинаково.
Группировка и агрегация
Используйте `@group` для группировки результатов и агрегатные функции в `@select`. Параметр `@having` фильтрует сгруппированные результаты.
Простая группировка
Группировка по одному полю с подсчетом:
@group=category&@select=category,@count(id):totalАгрегатные функции
| Функция | Описание | Пример |
|---|---|---|
| `@count(field)` | Количество записей | @count(id):total_users |
| `@sum(field)` | Сумма значений | @sum(amount):total_amount |
| `@avg(field)` | Среднее значение | @avg(price):avg_price |
| `@min(field)` | Минимальное значение | @min(price):min_price |
| `@max(field)` | Максимальное значение | @max(date):latest_date |
Множественная группировка
Группировка по нескольким полям:
@group=category,status&@select=category,status,@count(id):totalФильтрация с @having
Фильтруйте сгруппированные результаты по агрегатным значениям:
@group=category&@select=category,@count(id):total&@having=total(gt)=5Вернет только категории, в которых более 5 записей.
Комплексный пример
Статистика продаж по категориям и статусам:
@group=category,status
&@select=category,status,@count(id):total_orders,@sum(amount):total_sales,@avg(amount):avg_order
&@having=total_orders(gte)=10
&@order=total_sales:descВажно
При использовании @group, все поля в @select должны быть либо в списке группировки, либо использоваться в агрегатных функциях.
Пагинация
Управляйте выводом данных с помощью `@page`/`@size` для постраничной навигации или `@limit`/`@offset` для прямого указания диапазона.
Постраничная пагинация
Используйте @page и @size для навигации по страницам:
@page=2&@size=10Возвращает 10 записей со второй страницы (записи 11-20).
Пагинация через LIMIT/OFFSET
@limit=20&@offset=40Возвращает 20 записей, начиная с 41-й записи.
Формат ответа с пагинацией
При использовании @page и @size, API возвращает расширенный объект:
{
"list": [...], // Массив записей
"count": 156, // Общее количество записей
"pages": 16, // Всего страниц
"page": 2, // Текущая страница
"pagination": [ // Массив для UI пагинации
{"label": "prev", "page": 1},
{"label": 1, "page": 1},
{"label": 2, "page": 2},
...
{"label": "next", "page": 3}
]
}Ограничения
По умолчанию API ограничивает результаты до 1000 записей. Для больших наборов данных используйте пагинацию.
Работа с JSON полями
API поддерживает специальное поле `_json` для хранения произвольных данных и автоматически обрабатывает вложенные структуры.
Автоматическое поднятие полей
Поля из `_json` автоматически становятся доступными на верхнем уровне:
// Структура в БД:
{
"id": "user123",
"name": "Иван",
"_json": {
"avatar": "http://...",
"bio": "Программист"
}
}
// API вернет:
{
"id": "user123",
"name": "Иван",
"avatar": "http://...",
"bio": "Программист"
}Dot notation для фильтрации
Используйте точечную нотацию для доступа к вложенным полям:
// Фильтр по вложенному полю
profile.settings.theme=dark
// Фильтр по полю в массиве
tags.0=importantDot notation в @set
При создании или обновлении используйте dot notation для вложенных структур:
POST /api/update/users/user123
{
"@set": {
"profile.avatar.url": "http://example.com/avatar.jpg",
"profile.avatar.size": 1024,
"settings.notifications.email": true
}
}Это создаст или обновит вложенную структуру в поле _json.
Выбор JSON полей в @select
@select=id,name,profile.avatar,settings.themeПримечание
Поля, которых нет в схеме таблицы, автоматически сохраняются в _json при CREATE/UPDATE операциях.
Комплексные примеры
Практические примеры использования API для решения реальных задач.
Пример 1: Поиск активных пользователей с JOIN
Получить список активных пользователей с их заказами, отсортированных по дате регистрации:
GET /api/list/users?status=active&@join=["left:orders[users.id=orders.user_id]"]&@select=users.id,users.name,users.email,orders.total:order_total&@order=users.created_at:desc&@page=1&@size=20Пример 2: Создание пользователя с вложенным профилем
Создать нового пользователя с профилем и настройками:
POST /api/create/users
Content-Type: application/json
{
"@set": {
"name": "Иван Иванов",
"email": "ivan@example.com",
"status": "active",
"profile.avatar": "https://example.com/avatar.jpg",
"profile.bio": "Разработчик",
"settings.theme": "dark",
"settings.notifications.email": true,
"settings.notifications.push": false
},
"@return": "id,name,email,profile,settings,created_at"
}Пример 3: Сложная фильтрация с логическими операциями
Найти заказы со сложными условиями:
POST /api/list/orders
Content-Type: application/json
{
"@and": [
{
"@or": [
{"status": "pending"},
{"status": "processing"}
]
},
{"total(gte)": 100},
{"created_at(gte)": "2025-01-01"}
],
"@order": "created_at:desc",
"@page": 1,
"@size": 50
}Пример 4: Статистика с группировкой
Получить статистику продаж по категориям:
GET /api/list/orders?@group=category,status&@select=category,status,@count(id):total_orders,@sum(total):revenue,@avg(total):avg_order_value&@having=total_orders(gte)=10&@order=revenue:descПример 5: Массовое обновление с условием (POST)
Обновить статус всех неактивных пользователей:
POST /api/update/users
{
"last_login(lt)": "2024-01-01",
"status": "active",
"@set": {
"status": "inactive",
"deactivated_at": "2025-11-11"
},
"@return": "id,name,email,status"
}Пример 5.1: Обновление через GET с @set
Быстрое обновление одной записи через GET запрос:
GET /api/update/users/user123?@set=status=verified&role=premium&last_seen=2025-11-11&@return=id,name,status,roleТо же самое с квадратными скобками (рекомендуется для читаемости):
GET /api/update/users/user123?@set=[status=verified&role=premium&last_seen=2025-11-11]&@return=id,name,status,roleОбновление токенов (реальный пример):
GET /api/update/users/user123?@set=[firebaseToken=abc123xyz&mobileFirebaseToken=mobile456def&webToken=web789ghi]&@return=id,name,firebaseTokenОбновление вложенных JSON полей через GET:
GET /api/update/users/user123?@set=[profile.avatar.url=https://cdn.example.com/avatar.jpg&profile.avatar.size=2048&settings.theme=dark]&@return=profile,settingsМассовое обновление с условиями через GET:
GET /api/update/orders?status=pending&created_at(lt)=2025-01-01&@set=[status=cancelled&cancelled_reason=Expired]&@return=id,status,cancelled_reason✅ Преимущества квадратных скобок:
- Чёткое визуальное отделение параметров @set от условий фильтрации
- Улучшенная читаемость при большом количестве полей
- Уменьшение ошибок при формировании URL
💡 GET запросы удобны для простых обновлений и могут быть легко использованы в URL, но для сложных операций рекомендуется POST.
Пример 6: Поиск по вложенным JSON полям
Найти пользователей с определенными настройками:
POST /api/list/users
{
"settings.theme": "dark",
"profile.verified": true,
"tags(in)": ["premium", "verified"],
"@select": "id,name,email,profile.avatar,settings.theme",
"@return": "id,name,email,profile,settings"
}Пример 7: Работа с пустыми значениями
Найти пользователей без аватара или биографии:
GET /api/list/users?@or=(profile.avatar(empty)=true&profile.bio(empty)=true)&status=active&@select=id,name,email,profileПример 8: Операция SAVE (создать или обновить)
Создать или обновить пользователя:
POST /api/save/users
{
"@set": {
"id": "user123",
"name": "Иван Иванов (обновлено)",
"email": "ivan.new@example.com",
"profile.updated_at": "2025-11-11"
},
"@return": "id,name,email,created_at,updated_at"
}Если user123 существует - обновит, если нет - создаст новую запись.
Интерактивный конструктор запросов
Используйте эту форму, чтобы визуально построить ваш API-запрос. URL и команда cURL будут сгенерированы автоматически.
Фильтры
Сгенерированные запросы
GET-запрос (URL)
POST-запрос (cURL)