Концепции · 0.8.1

API приложения: записи, связи и изображения

Маршруты admin и external, параметры списков, правила чтения и структуры OpenAPI.

На этой странице

API приложения читает и меняет записи PostgreSQL. Не путайте его с локальным API генератора, который редактирует модель. Конкретные маршруты зависят от модулей, имён сущностей, операций и доступа — смотрите OpenAPI своего проекта.

Как подготовить API через UI

  1. В Content → нужная сущность → настройки → Access выберите операции и внешний доступ. В External READ access задайте обязательные условия чтения.
  2. У полей в Advanced settings → List behavior включите нужные Searchable, Filterable, Sortable. Для virtual отдельно настройте выбранные поля связей и коллекций.
  3. Проверьте маршруты в Access → Generated routes.
  4. Выполните Generate → Preview changes → Generate и запустите backend с обновлённым кодом.

Дальнейшие примеры нужны разработчику интеграции. Для обычного ввода данных используйте систему администрирования — HTTP-запросы вручную не требуются.

Административные и внешние маршруты

Для модуля content и сущности с маршрутом articles используются два базовых адреса:

/api/admin/v1/content/articles
/api/external/v1/content/articles
Метод Путь от базового адреса Что делает
GET Базовый путь Возвращает список.
GET /{id} Возвращает одну запись.
POST Базовый путь Создаёт запись.
PATCH /{id} Обновляет запись по контракту объекта.
DELETE /{id} Удаляет запись.

Admin API требует соответствующих прав. Для каждой external-операции выбирается off, authenticated или anonymous: отключена, требует входа или допускает анонимный запрос. Разрешение чтения не открывает запись.

PATCH не означает автоматическое объединение произвольного набора полей с записью. Передавайте объект по документированному контракту и сохраняйте актуальные поля модели.

Пагинация, поиск и фильтры

Список возвращает {items, total, limit, offset}. Одна страница содержит не более 100 записей. Для продолжения клиент запрашивает следующие страницы.

Используйте только поля с включёнными возможностями поиска, фильтрации и сортировки:

Параметр Содержимое
searches JSON-массив условий field/value.
filters Условия field/op/value.
sort, order Поле и направление сортировки.

Например, для отбора по slug или status у поля должен быть включён Filterable. Имена полей проверяются сервером, а значения передаются в SQL параметрами.

Запрос из терминала:

curl --fail --get \
  --data-urlencode 'limit=20' --data-urlencode 'offset=0' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  http://127.0.0.1:8081/api/admin/v1/content/articles

В ACCESS_TOKEN должен быть уже полученный токен сессии. Подставьте свои адрес и маршрут. Не сохраняйте административный токен в файлы сайта. Для посетителей сайта используйте external API с правилами чтения.

Язык ответа и сохранение переводов

Сначала настройте языки и переводимые поля в Entity settings → Languages, выполните Generate, примените миграции и обновите приложение. locale выбирает язык данных, а не язык интерфейса. Он действует на list/get, поиск, фильтры, сортировку и выбранные поля virtual, включая вложенные коллекции.

Например, для товара Product в модуле catalog с числовым ID 1:

curl --fail 'http://127.0.0.1:8081/api/external/v1/catalog/products/1?locale=ru'

Здесь предполагается, что external get разрешён анонимно. Подставьте свой адрес, модуль, маршрут и ID; для authenticated-запроса дополнительно нужен токен. Параметр языка не выдаёт доступ к записи.

Пример ответа, если перевод заполнен:

{
  "id": 1,
  "name": "Кружка",
  "description": "Керамическая кружка.",
  "price": 1490,
  "categoryId": 2
}

Имена name и description не меняются на name-ru или description-ru: суффиксы видны только в подписях формы. Без locale каждая исходная сущность использует свой основной язык. Если у persistent-сущности с включёнными языками запрошенный язык не настроен, API вернёт HTTP 400. Virtual принимает объединённый набор языков своих выбранных переводимых полей.

При отсутствии перевода результат определяется Missing translation у владельца поля: null либо значение этого поля на основном языке. Подстановка отдельная для каждого поля. У связанной сущности с другим набором языков действует её собственное правило. Отсутствие перевода не обходит явно настроенные условия чтения.

Admin API дополнительно читает и принимает _translations. Например, при PATCH существующего товара можно передать общие поля записи и изменить только русский перевод:

{
  "id": 1,
  "price": 1490,
  "categoryId": 2,
  "_translations": {
    "ru": {
      "name": "Кружка с ручкой",
      "description": "Керамическая кружка, 300 мл."
    }
  }
}

Пример относится к модели с перечисленными полями. Если в вашей модели есть другие общие поля, передайте их по контракту своего объекта. Отсутствующие языки и ячейки внутри _translations сохраняются; явный null очищает перевод, если правила обязательности это допускают. Это специальное объединение переводов, а не разрешение отправлять произвольный неполный PATCH общих полей. В external-ответах _translations не возвращается. Нарушение уникальности переводимого поля в том же языке возвращает HTTP 409; одинаковые значения в разных языках сами по себе не конфликтуют.

Связанные записи

К базовому адресу сущности добавляются следующие пути:

Суффикс Действие
/relations/{relation}/options GET: получить ограниченный список для выбора.
/relations/{relation}/options/{targetId} GET: получить подпись и данные выбранной записи.
/{sourceId}/relations/{relation} GET: прочитать связанные записи.
/{sourceId}/relations/{relation}/{targetId} POST/DELETE: изменить состав manyToMany со стороны владельца.

Чтение проверяет права на исходную и целевую сущности. Для изменения состава нужны разрешения владельца и цели. Virtual доступны только для чтения; их ответы отдельно описаны в OpenAPI.

Изображения

Административные операции находятся под /api/admin/v1/_media/{entity}/{field}: POST /uploads, GET /{assetId}, GET /{assetId}/files/{variant}, POST /{assetId}/process. Они проверяют доступ, размер файла и состояние обработки. Ссылка в JSON не открывает анонимный доступ к приватным операциям загрузки и обработки.

Внешний ответ содержит карту size с готовыми URL вариантов. Его контракт отличается от административного контракта медиа.

Обязательные правила чтения

Условия external list/get применяются до пагинации и подсчёта total. Если запись недоступна по правилу, get вернёт 404. Можно использовать AND/OR, скалярные поля и один переход belongsTo. У коллекций virtual отдельные правила и параметры — см. проекции.

Как читать OpenAPI и ошибки

OpenAPI описывает persistent- и virtual-ответы: поля, типы, nullable и enum. Объекты записи отделены от ответов. Используйте эту схему при разработке клиента.

Проверяйте HTTP-статус и структурированную ошибку. Идентификатор запроса помогает найти событие в журнале. Пустой результат не доказывает удаление записи, а ошибка сети не означает её отсутствия. Аккаунты и сессии описаны в аутентификации.

Состав данных настраивается в полях и виртуальных сущностях, маршруты и обязательные условия — в Access.