---
title: "Web Services в Joomla 4 - WebTolk"
description: "Работа с REST API Web Services в Joomla 4 и Joomla 5: получение, удаление, создание материалов. Примеры Joomla Framework и CURL. Перевод документации."
url: "https://web-tolk.ru/blog/web-services-v-joomla-4"
date: "2023-12-20T06:08:51+00:00"
language: "ru-RU"
---

# Web Services в Joomla 4

 Автор: Сергей Толкачев Создано: 20 декабря 2023 Обновлено: 20 декабря 2023 Просмотров: 1640    ![](https://web-tolk.ru/blog/images/blog/web-services-v-joomla-4/header-1920x1080.webp)

Этот текст - [перевод](https://manual.joomla.org/docs/general-concepts/webservices)статьи из [нового портала документации для разработчиков Joomla](https://manual.joomla.org/), раздел "Основные концепции". Ранее уже был опубликован перевод раздела, описывающего принципы [Dependency Injection Containers в Joomla 4](https://web-tolk.ru/blog/index.php?option=com_content&view=article&id=62:dependency-injection-containers-di-kontejnery-v-joomla-4&catid=10:blog&lang=ru-RU&Itemid=114). Первоначально эта статья была опубликована в моём блоге на Хабре. Копирую к себе.

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

- Веб-сервисы используются для взаимодействия различных систем друг с другом с помощью протокола HTTP, а в настоящее время и через TLS (безопасность транспортного уровня).
- Веб-сервисы действуют как контракт между поставщиком сервиса и потребителем сервиса через Endpoint.
- Веб-сервисы подобны дверям и окнам в доме, они являются ВХОДАМИ (inputs) и ВЫХОДАМИ (outputs) во ВНЕШНИЙ мир.
- В контексте Joomla как системы в целом, Joomla Web services API позволяет Joomla взаимодействовать с внешними источниками данных. Например, веб-приложениями, мобильными приложениями и т.д.

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

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

- [Список endpoint'ов ядра Joomla](https://docs.joomla.org/J4.x:Joomla_Core_APIs) (официальная документация Joomla)
- [Коллекция Joomla endpoints для работы с Postman](https://github.com/alexandreelise/j4x-api-collection) (GitHub)

## Использование 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) на Хабре - Т.С.](https://web-tolk.ru/blog/index.php?option=com_content&view=article&id=39:sozdanie-vneshnikh-zaprosov-s-ispolzovaniem-httpfactory-joomla&catid=10:blog&lang=ru-RU&Itemid=114)]

Поместите Ваш токен Joomla! Api token в безопасное место, например, в менеджер паролей или хранилище. Мы не рекомендуем использовать переменные окружения для хранения паролей. Здесь описано почему - статья "[Analyzing the Hidden Danger of Environment Variables for Keeping Secrets](https://www.trendmicro.com/en_us/research/22/h/analyzing-hidden-danger-of-environment-variables-for-keeping-secrets.html)" на 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 uri class](https://web-tolk.ru/blog/images/blog/web-services-v-joomla-4/joomla-uri-class-help.webp)Составные части URL так, как они обрабатываются методами класса Joomla\Uri\Uri
- [Официальная документация Joomla по классу Joomla\Uri\Uri](https://docs.joomla.org/URLs_in_Joomla)
- Доки для 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 database screenshot](https://web-tolk.ru/blog/images/blog/web-services-v-joomla-4/joomla-database-screenshot.webp)

Если контент-менеджер с помощью вставки линии "подробнее" в админке указал 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;
```

- [Изначальная публикация на Habr.com](https://habr.com/ru/articles/747730/)

## Об авторе

![Толкачев Сергей Юрьевич](https://web-tolk.ru/images/uslugi/sergey-tolkachyov-apr-2023.webp)

### Толкачев Сергей Юрьевич

Joomla-разработчик. [Контрибьютер ядра Joomla](https://github.com/joomla/joomla-cms/pulls?q=is%3Apr+author%3Asergeytolkachyov+). Один из ведущих Telegram-канала русскоязычного Joomla-сообщества [JoomlaFeed](https://t.me/joomlafeed), один из модераторов [чата русскоязычного Joomla-сообщества](https://t.me/joomlaru). Мои расширения в официальном маркетплейсе расширений Joomla - [Joomla Extensions Directory](https://extensions.joomla.org/profile/profile/details/528051/). Имею публикации в [официальном журнале международного Joomla-сообщества - Joomla Community Magazine](https://magazine.joomla.org/authors/sergeytolkachyov) и на [официальном сайте русскоязычного Joomla-сообщества](https://joomlaportal.ru/users/sergey-tolkachyov).

Муж. Отец 3 детей.

Россия, Саратов.

## JSON-LD Schema

```json
{
    "@context": "https://schema.org",
    "@type": "BreadcrumbList",
    "@id": "https://web-tolk.ru/#/schema/BreadcrumbList/17",
    "itemListElement": [
        {
            "@type": "ListItem",
            "position": 1,
            "item": {
                "@id": "https://web-tolk.ru/",
                "name": "Главная"
            }
        },
        {
            "@type": "ListItem",
            "position": 2,
            "item": {
                "@id": "https://web-tolk.ru/blog",
                "name": "Блог"
            }
        },
        {
            "@type": "ListItem",
            "position": 3,
            "item": {
                "name": "Web Services в Joomla 4"
            }
        }
    ]
}
```

```json
{
    "@context": "https://schema.org",
    "@graph": [
        {
            "@type": "Organization",
            "@id": "https://web-tolk.ru/#/schema/Organization/base",
            "name": "WebTolk",
            "url": "https://web-tolk.ru/",
            "logo": {
                "@type": "ImageObject",
                "@id": "https://web-tolk.ru/#/schema/ImageObject/logo",
                "url": "images/webtolk-1080p.jpg",
                "contentUrl": "images/webtolk-1080p.jpg",
                "width": 1920,
                "height": 1080
            },
            "image": {
                "@id": "https://web-tolk.ru/#/schema/ImageObject/logo"
            },
            "sameAs": [
                "https://github.com/WebTolk",
                "https://github.com/sergeytolkachyov",
                "https://vk.com/web_tolk",
                "https://vk.com/webtolkru",
                "https://tenchat.ru/sergeytolkachyov",
                "https://t.me/sergeytolkachyov",
                "https://t.me/webtolkru"
            ]
        },
        {
            "@type": "WebSite",
            "@id": "https://web-tolk.ru/#/schema/WebSite/base",
            "url": "https://web-tolk.ru/",
            "name": "WebTolk",
            "publisher": {
                "@id": "https://web-tolk.ru/#/schema/Organization/base"
            }
        },
        {
            "@type": "WebPage",
            "@id": "https://web-tolk.ru/#/schema/WebPage/base",
            "url": "https://web-tolk.ru/blog/web-services-v-joomla-4",
            "name": "Web Services в Joomla 4 - WebTolk",
            "description": "Работа с REST API Web Services в Joomla 4 и Joomla 5: получение, удаление, создание материалов. Примеры Joomla Framework и CURL. Перевод документации.",
            "isPartOf": {
                "@id": "https://web-tolk.ru/#/schema/WebSite/base"
            },
            "about": {
                "@id": "https://web-tolk.ru/#/schema/Organization/base"
            },
            "inLanguage": "ru-RU",
            "breadcrumb": {
                "@id": "https://web-tolk.ru/#/schema/BreadcrumbList/17"
            }
        },
        {
            "@type": "Article",
            "@id": "https://web-tolk.ru/#/schema/com_content/article/83",
            "name": "Web Services в Joomla 4",
            "headline": "Web Services в Joomla 4",
            "inLanguage": "ru-RU",
            "author": {
                "@type": "Person",
                "name": "Сергей Толкачев"
            },
            "thumbnailUrl": "images/blog/web-services-v-joomla-4/header-1920x1080.webp",
            "image": "images/blog/web-services-v-joomla-4/header-1920x1080.webp",
            "dateModified": "2023-12-20T00:00:00+00:00",
            "interactionStatistic": {
                "@type": "InteractionCounter",
                "userInteractionCount": 1640
            },
            "isPartOf": {
                "@id": "https://web-tolk.ru/#/schema/WebPage/base"
            }
        }
    ]
}
```
