Веб-сервисы API
Joomla отдаёт данные не только страницами HTML, но и через API — в формате JSON, для мобильных приложений и обмена с другими системами. У API своя точка входа, api/index.php, и своя, третья часть компонента в папке api. Сначала посмотрим на встроенный API, затем добавим в него записи блога.
Встроенный API
| Запрос | Что делает |
|---|---|
GET /api/index.php/v1/content/articles | Список статей |
GET /api/index.php/v1/content/articles/1 | Одна статья |
POST /api/index.php/v1/content/articles | Создать статью |
PATCH /api/index.php/v1/content/articles/1 | Изменить статью |
DELETE /api/index.php/v1/content/articles/1 | Удалить статью |
Токен
Запросы к API подписывают токеном. Откройте в панели свой профиль («Пользователи → Управление», затем свою учётную запись), вкладку «Токен Joomla API», и скопируйте токен. Должны быть включены плагины «API Authentication — Web Services Joomla Token» и «User — Joomla API Token».
curl http://joomla.test/api/index.php/v1/content/articles \
-H "X-Joomla-Token: ваш_токен"В ответ придёт JSON со списком статей. Запрос выполняется с правами владельца токена.
Что нужно для своего компонента
plugins/webservices/hello/ плагин: объявляет адреса
├── hello.xml
├── services/provider.php
└── src/Extension/Hello.php
api/components/com_hello/ часть компонента для API
└── src/
├── Controller/
│ └── PostsController.php
└── View/
└── Posts/
└── JsonapiView.phpВсе файлы создают вручную. В манифест компонента добавьте раздел:
<!-- administrator/components/com_hello/hello.xml -->
<api>
<files folder="api">
<folder>src</folder>
</files>
</api>Плагин с маршрутами
Манифест и провайдер плагина — как у плагина content, только группа webservices и пространство имён My\Plugin\WebServices\Hello. Класс:
// plugins/webservices/hello/src/Extension/Hello.php
namespace My\Plugin\WebServices\Hello\Extension;
defined('_JEXEC') or die;
use Joomla\CMS\Event\Application\BeforeApiRouteEvent;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\Event\SubscriberInterface;
final class Hello extends CMSPlugin implements SubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
'onBeforeApiRoute' => 'registerRoutes',
];
}
public function registerRoutes(BeforeApiRouteEvent $event): void
{
$event->getRouter()->createCRUDRoutes(
'v1/hello/posts',
'posts',
['component' => 'com_hello'],
);
}
}createCRUDRoutes() объявляет сразу пять адресов: список, одна запись, создание, изменение, удаление. Второй аргумент — имя контроллера. Класс события BeforeApiRouteEvent есть в Joomla 5; в Joomla 4 обработчик получает маршрутизатор аргументом.
Контроллер
// api/components/com_hello/src/Controller/PostsController.php
namespace My\Component\Hello\Api\Controller;
defined('_JEXEC') or die;
use Joomla\CMS\MVC\Controller\ApiController;
class PostsController extends ApiController
{
protected $contentType = 'posts';
protected $default_view = 'posts';
}Вся работа уже написана в ApiController. Модели он берёт из административной части компонента: PostsModel для списка и PostModel для одной записи.
Представление
// api/components/com_hello/src/View/Posts/JsonapiView.php
namespace My\Component\Hello\Api\View\Posts;
defined('_JEXEC') or die;
use Joomla\CMS\MVC\View\JsonApiView as BaseApiView;
class JsonapiView extends BaseApiView
{
protected $fieldsToRenderList = ['id', 'title', 'created'];
protected $fieldsToRenderItem = ['id', 'title', 'body', 'created'];
}Два списка задают, какие поля попадут в ответ: для списка записей и для одной записи.
Результат
Установите плагин через «Поиск» и включите его. Затем выполните:
curl http://joomla.test/api/index.php/v1/hello/posts \
-H "X-Joomla-Token: ваш_токен"Ответ — JSON в формате JSON:API: массив data, где у каждой записи есть type, id и attributes с заголовком и датой. Адрес v1/hello/posts/1 вернёт одну запись вместе с текстом.
Частая ошибка
Токен API даёт те же права, что и учётная запись его владельца. Токен суперпользователя, зашитый в мобильное приложение или в скрипт на чужом сервере, — это полный доступ к сайту для любого, кто его найдёт. Заведите для обмена отдельного пользователя с наименьшими нужными правами и храните токен как пароль.