Web Services в Joomla 4

от автора

Этот текст — перевод статьи из нового портала документации для разработчиков Joomla, раздел «Основные концепции». Ранее уже был опубликован перевод раздела, описывающего принципы Dependency Injection Containers в Joomla 4.


Концепция веб-сервисов

  • Веб-сервисы используются для взаимодействия различных систем друг с другом с помощью протокола HTTP, а в настоящее время и через TLS (безопасность транспортного уровня).

  • Веб-сервисы действуют как контракт между поставщиком сервиса и потребителем сервиса через Endpoint.

  • Веб-сервисы подобны дверям и окнам в доме, они являются ВХОДАМИ (inputs) и ВЫХОДАМИ (outputs) во ВНЕШНИЙ мир.

  • В контексте Joomla как системы в целом, Joomla Web services API позволяет Joomla взаимодействовать с внешними источниками данных. Например, веб-приложениями, мобильными приложениями и т.д.

Взаимодействие с Web Services API Joomla 4.x

Взаимодействие с API веб-сервисов Joomla 4 происходит через определённые endpoint’ы:

Использование Joomla API

Чаще всего, при использовании Joomla API, под капотом по-прежнему используется cURL или php. Чаще всего cURL доступен на Вашем хостинге. В противном случае проверьте с помощью phpinfo();

Определим переменные

Сначала мы определим некоторые переменные, которые будем использовать во всех наших запросах:

  • URL нашего сайта на Joomla 4.x

  • Токен Joomla API учетной записи суперпользователя или учетной записи, у которой есть, по крайней мере, разрешение core.login.api и core.login.site, чтобы иметь возможность видеть изменение токена текущего пользователя, вошедшего в систему.

<?php // Before passing the HTTP METHOD to CURL use Joomla\Http\HttpFactory; use Joomla\Uri\Uri;  $http = (new HttpFactory())->getAvailableDriver(); $url   = 'https://example.org/api/index.php/v1'; $uri  = new Uri($url);  // Поместите Ваш токен Joomla! Api token в безопасное место, // например, в менеджер паролей или хранилище. // Мы не рекомендуем использовать переменные окружения // для хранения паролей. // Здесь описано почему: https://www.trendmicro.com/en_us/research/22/h/analyzing-hidden-danger-of-environment-variables-for-keeping-secrets.html  $token = '';

[Статья Создание внешних запросов с использованием HttpFactory (Joomla) на Хабре — Т.С.]

Поместите Ваш токен Joomla! Api token в безопасное место, например, в менеджер паролей или хранилище. Мы не рекомендуем использовать переменные окружения для хранения паролей. Здесь описано почему — статья «Analyzing the Hidden Danger of Environment Variables for Keeping Secrets» на TrendMicro.com.

POST — Создание материала Joomla в категории «Uncategorized» («Без категории») по REST API (ID категории = 2)

<?php use Joomla\Http\HttpFactory; use Joomla\Uri\Uri;  $http = (new HttpFactory())->getAvailableDriver(); $url   = 'https://example.org/api/index.php/v1'; $uri  = new Uri($url);  $token = '';  $categoryId = 2; // Категория "Без категории" Joomla по умолчанию  $data = [ 'title'       => 'Как добавить материал Joomla с помощью REST API?', 'alias'       => 'кak-dobavit-material-joomla-s-pomoshhju-rest-api', 'articletext' => 'Я пока не знаю... Поищу-ка я новенькие статьи о Joomla на Хабре.', 'catid'       => $categoryId, 'language'    => '*', 'metadesc'    => '', 'metakey'     => '', ];  $dataString = json_encode($data);  // HTTP request headers $headers = [ 'Accept: application/vnd.api+json', 'Content-Type: application/json', 'Content-Length: ' . mb_strlen($dataString), sprintf('X-Joomla-Token: %s', trim($token)), ];  // Таймаут в секундах $timeout = 30;  // Установите endpoint для работы с материалами. // Это часть $uri. $uri->setPath('content/articles');  // Это будет PSR-7 совместимый Response $response = $http->request('POST', $uri, $dataString, $headers, $timeout);  // В результате запроса мы имеем stream, поэтому делаем просто: echo $response->body;

Небольшое отступление о классе Uri в Joomla (от переводчика)

Для большего понимания происходящего в коде и дальнейшей более удобной работы с Joomla API позволю себе внедрить краткую справку о классах Uri в Joomla:

  • Официальная документация Joomla по классу Joomla\Uri\Uri

  • Доки для Joomla 3, но класс Uri в Joomla 4 остался в целом тем же.

  • В документации по ссылке указан класс Joomla\CMS\Uri\Uri, который расширяет класс Joomla\Uri\Uri, который в свою очередь, расширяет класс Joomla\Uri\AbstractUri. Методы родительского класса доступны в дочернем.

  • Класс Joomla\Uri\Uri предназначен для работы с url и позволяет работать с ним как с объектом: $url->setPath, $url->setScheme, $url->setScheme , $url->setScheme и другими методами (список смотрим в файле класса: libraries/vendor/joomla/uri/src/Uri.php). Соответствующие геттеры заданы в классе Joomla\Uri\AbstractUri

  • Класс Joomla\CMS\Uri\Uri добавляет несколько методов, которые необходимы для больше внутренней работы Joomla: определение внешний ли или внутренний url, текущий url без GET-параметров и т.д.

GET — Получение списка всех материалов Joomla из категории «Uncategorized» («Без категории»)

<?php use Joomla\Http\HttpFactory; use Joomla\Uri\Uri;  $http = (new HttpFactory())->getAvailableDriver(); $url   = 'https://example.org/api/index.php/v1'; $uri  = new Uri($url);  $token = '';  $categoryId = 2; // Категория "Без категории" Joomla по умолчанию  // Не будем отправлять payload на сервер $dataString = null;  // HTTP заголовки запроса $headers = [ 'Accept: application/vnd.api+json', 'Content-Type: application/json', sprintf('X-Joomla-Token: %s', trim($token)), ];  // Таймаут в секундах $timeout = 30;  // Установите endpoint для работы с материалами. // Это часть $uri. $uri->setPath('content/articles');  // Это будет PSR-7 совместимый Response $response = $http->request('GET', $uri, $dataString, $headers, $timeout);  // В результате запроса мы имеем stream, поэтому делаем просто: echo $response->body;

GET — Получение материала Joomla по id (REST API)

<?php use Joomla\Http\HttpFactory; use Joomla\Uri\Uri;  $http = (new HttpFactory())->getAvailableDriver(); $url   = 'https://example.org/api/index.php/v1'; $uri  = new Uri($url);  $token = '';  $articleId = 1; // ID нужной статьи в Joomla  // Не будем отправлять payload на сервер $dataString = null;  // HTTP заголовки запроса $headers = [ 'Accept: application/vnd.api+json', 'Content-Type: application/json', sprintf('X-Joomla-Token: %s', trim($token)), ];  // Таймаут в секундах $timeout = 30;  // Устанавливаем path-часть Url для получения конкретного материала. $uri->setPath(sprintf('content/articles/%d', $articleId));  // Это будет PSR-7 совместимый Response $response = $http->request('GET', $uri, $dataString, $headers, $timeout);  // В результате запроса мы имеем stream, поэтому делаем просто: echo $response->body;

PATCH — Изменение материала Joomla по id (REST API)

<?php use Joomla\Http\HttpFactory; use Joomla\Uri\Uri;  $http = (new HttpFactory())->getAvailableDriver(); $url   = 'https://example.org/api/index.php/v1'; $uri  = new Uri($url);  $token = ''; $articleId = 1; // ID нужной статьи в Joomla  $data = [ 'id'          => $articleId, 'title'       => 'Как добавить материал Joomla с помощью REST API?', 'introtext' => 'При использовании PATCH текст статьи должен быть разделен на две части или использовать, по крайней мере, только introtext, чтобы сохранить данные должным образом', 'fulltext' => 'Больше контента богу контента!', ];  $dataString = json_encode($data);  // HTTP заголовки запроса $headers = [ 'Accept: application/vnd.api+json', 'Content-Type: application/json', 'Content-Length: ' . mb_strlen($dataString), sprintf('X-Joomla-Token: %s', trim($token)), ];  // Таймаут в секундах $timeout = 30;  // Устанавливаем path-часть Url для изменения конкретного материала. $uri->setPath(sprintf('content/articles/%d', $articleId));  // Это будет PSR-7 совместимый Response $response = $http->request('PATCH', $uri, $dataString, $headers, $timeout);  // Здесь получим status code запроса echo $response->code;

Примечание переводчика о структуре сущности материала Joomla

Примечание переводчика для разработчиков, не знакомых со структурой компонента материалов (com_content) Joomla. Каждый материал (article) имеет вступительный текст и вводный текст. Вступительный текст отображается в списке материалов в виде блога (с картинкой вступительного текста, парой абзацев и кнопкой «подробнее»). Полный текст материала отображается, соответственно, когда пользователь хочет читать статью полностью и открывает её.

В базе данных в таблице для материалов Joomla реализовано 2 ячейки: introtext и fulltext типа MEDIUMTEXT соответственно.

Если контент-менеджер с помощью вставки линии «подробнее» в админке указал Joomla, что текст нужно разбить на вступительную и полную часть, то текст будет разрезан на 2 части и каждая из частей будет храниться в своей ячейке. Если же линия «подробнее» не вставлена, то весь текст хранится в ячейке introtext.

Таким образом при работе с REST API нужно представлять КАК происходит работа с текстом на всех этапах: создание, редактирование, отображение редактору, отображение пользователю сайта. Если Joomla используется как бэкенд, а фронт — это мобильное приложение или фронт сделан на js-фреймворке, то отображение зависит уже не от Joomla, а от реализации приложения и тогда весь текст материала можно хранить в introtext. Если же REST API используется при редактировании, а для посетителей используется HTML-вывод Joomla, то соблюдение правил игры CMS будет важным, так как это будет влиять на отображение для пользователей сайта.

DELETE — Удаление материала Joomla по id (REST API)

<?php use Joomla\Http\HttpFactory; use Joomla\Uri\Uri;  $http = (new HttpFactory())->getAvailableDriver(); $url   = 'https://example.org/api/index.php/v1'; $uri  = new Uri($url);  $token = ''; $articleId = 1; // ID нужной статьи в Joomla  // Не будем отправлять payload на сервер $dataString = null;  // HTTP заголовки запроса $headers = [ 'Accept: application/vnd.api+json', 'Content-Type: application/json', sprintf('X-Joomla-Token: %s', trim($token)), ];  // Таймаут в секундах $timeout = 30;  // Устанавливаем path-часть Url для удаления конкретного материала. $uri->setPath(sprintf('content/articles/%d', $articleId));  // Это будет PSR-7 совместимый Response $response = $http->request('DELETE', $uri, $dataString, $headers, $timeout);  // Здесь получим status code запроса echo $response->code;

Запросы к REST API Joomla с использованием чистого PHP cURL

Перед использованием этого кода удостоверьтесь, что cURL установлен на Вашем хостинге, проверьте с помощью phpinfo(). [Данный раздел документации может пригодится для non-Joomla сайтов, которые будут взаимодействовать с Joomla 4+ сайтами — Т.С.]

Определим переменные

Сначала мы определим некоторые переменные, которые будем использовать во всех наших cURL  запросах:

  • URL нашего сайта на Joomla 4.x

  • Токен Joomla API учетной записи суперпользователя или учетной записи, у которой есть, по крайней мере, разрешение core.login.api и core.login.site, чтобы иметь возможность видеть изменение токена текущего пользователя, вошедшего в систему.

<?php // Before passing the HTTP METHOD to CURL $curl  = curl_init();  $url   = 'https://example.org/api/index.php/v1';  // Поместите Ваш токен Joomla! Api token в безопасное место, // например, в менеджер паролей или хранилище. // Мы не рекомендуем использовать переменные окружения // для хранения паролей. // Здесь описано почему: https://www.trendmicro.com/en_us/research/22/h/analyzing-hidden-danger-of-environment-variables-for-keeping-secrets.html $token = ''; 

POST — Создание материала Joomla в категории «Uncategorized» («Без категории») по REST API с помощью cURL

<?php // Before passing the HTTP METHOD to CURL $curl  = curl_init();  $url   = 'https://example.org/api/index.php/v1';  $token = '';  $categoryId = 2; // Joomla's default "Uncategorized" Category   $data = [ 'title'       => 'How to add an article to Joomla via the API?', 'alias'       => 'how-to-add-article-via-joomla-api', 'articletext' => 'I have no idea...', 'catid'       => $categoryId, 'language'    => '*', 'metadesc'    => '', 'metakey'     => '', ];  $dataString = json_encode($data);  // HTTP request headers $headers = [ 'Accept: application/vnd.api+json', 'Content-Type: application/json', 'Content-Length: ' . mb_strlen($dataString), sprintf('X-Joomla-Token: %s', trim($token)), ];  curl_setopt_array($curl, [         CURLOPT_URL            => sprintf('%s/%s',$url,'content/articles'),         CURLOPT_RETURNTRANSFER => true,         CURLOPT_ENCODING       => 'utf-8',         CURLOPT_MAXREDIRS      => 10,         CURLOPT_TIMEOUT        => 30,         CURLOPT_FOLLOWLOCATION => true,         CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_2TLS,         CURLOPT_CUSTOMREQUEST  => 'POST',         CURLOPT_POSTFIELDS     => $dataString,         CURLOPT_HTTPHEADER     => $headers,     ] );  $response = curl_exec($curl); curl_close($curl); echo $response;

GET — Получение списка всех материалов Joomla из категории «Uncategorized» («Без категории») с помощью cURL по REST API

<?php // Before passing the HTTP METHOD to CURL $curl  = curl_init();  $url   = 'https://example.org/api/index.php/v1';  $token = '';  $categoryId = 2; // Joomla's default "Uncategorized" Category   // HTTP request headers $headers = [ 'Accept: application/vnd.api+json', 'Content-Type: application/json', sprintf('X-Joomla-Token: %s', trim($token)), ];  curl_setopt_array($curl, [         CURLOPT_URL            => sprintf('%s/content/articles?filter[category]=%d',$url,$categoryId),         CURLOPT_RETURNTRANSFER => true,         CURLOPT_ENCODING       => 'utf-8',         CURLOPT_MAXREDIRS      => 10,         CURLOPT_TIMEOUT        => 30,         CURLOPT_FOLLOWLOCATION => true,         CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_2TLS,         CURLOPT_CUSTOMREQUEST  => 'GET',         CURLOPT_HTTPHEADER     => $headers,     ] );  $response = curl_exec($curl); curl_close($curl); echo $response;

GET — Получение конкретного материала Joomla по id с помощью cURL (REST API)

<?php // Before passing the HTTP METHOD to CURL $curl  = curl_init();  $url   = 'https://example.org/api/index.php/v1';  $token = '';  $articleId = 1; // The Article ID of a specific Article   // HTTP request headers $headers = [ 'Accept: application/vnd.api+json', 'Content-Type: application/json', sprintf('X-Joomla-Token: %s', trim($token)), ]; curl_setopt_array($curl, [         CURLOPT_URL            => sprintf('%s/content/articles/%d',$url,$articleId),         CURLOPT_RETURNTRANSFER => true,         CURLOPT_ENCODING       => 'utf-8',         CURLOPT_MAXREDIRS      => 10,         CURLOPT_TIMEOUT        => 30,         CURLOPT_FOLLOWLOCATION => true,         CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_2TLS,         CURLOPT_CUSTOMREQUEST  => 'GET',         CURLOPT_HTTPHEADER     => $headers,     ] );  $response = curl_exec($curl); curl_close($curl); echo $response;

PATCH — Изменение материала Joomla по id с помощью cURL (REST API)

<?php // Before passing the HTTP METHOD to CURL $curl  = curl_init();  $url   = 'https://example.org/api/index.php/v1';  $token = '';  $articleId = 1; // The Article ID of a specific Article   $data = [ 'id'          => $articleId, 'title'       => 'How to add an article via the Joomla 4 API?', 'introtext' => 'When using PATCH, articletext MUST be splitted in two parts or use at least just introtext in order to work properly', 'fulltext' => 'MORE CONTENT if you wish', ];  $dataString = json_encode($data);  // HTTP request headers $headers = [ 'Accept: application/vnd.api+json', 'Content-Type: application/json', 'Content-Length: ' . mb_strlen($dataString), sprintf('X-Joomla-Token: %s', trim($token)), ];  curl_setopt_array($curl, [         CURLOPT_URL            => sprintf('%s/content/articles/%d',$url,$articleId),         CURLOPT_RETURNTRANSFER => true,         CURLOPT_ENCODING       => 'utf-8',         CURLOPT_MAXREDIRS      => 10,         CURLOPT_TIMEOUT        => 30,         CURLOPT_FOLLOWLOCATION => true,         CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_2TLS,         CURLOPT_CUSTOMREQUEST  => 'PATCH',         CURLOPT_POSTFIELDS     => $dataString,         CURLOPT_HTTPHEADER     => $headers,     ] );  $response = curl_exec($curl); curl_close($curl); echo $response;

DELETE — Удаление материала Joomla по id с помощью cURL (REST API)

<?php // Before passing the HTTP METHOD to CURL $curl  = curl_init();  $url   = 'https://example.org/api/index.php/v1';  $token = '';  $articleId = 1; // The Article ID of a specific Article   // HTTP request headers $headers = [ 'Accept: application/vnd.api+json', 'Content-Type: application/json', sprintf('X-Joomla-Token: %s', trim($token)), ];  curl_setopt_array($curl, [         CURLOPT_URL            => sprintf('%s/content/articles/%d',$url,$articleId),         CURLOPT_RETURNTRANSFER => true,         CURLOPT_ENCODING       => 'utf-8',         CURLOPT_MAXREDIRS      => 10,         CURLOPT_TIMEOUT        => 30,         CURLOPT_FOLLOWLOCATION => true,         CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_2TLS,         CURLOPT_CUSTOMREQUEST  => 'DELETE',         CURLOPT_HTTPHEADER     => $headers,     ] );  $response = curl_exec($curl); curl_close($curl); echo $response;

Полезные ресурсы

Ресурсы Joomla сообщества:

Joomla в Telegram:


ссылка на оригинал статьи https://habr.com/ru/articles/747730/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *