Этот модуль позволяет организовать централизованные API для сайта, которое удобно поддерживать, легко вносить правки, легко обслуживать и допускать меньше ошибок, а также сокращать время на добавление новых методов.
Установить модуль можно отсюда - отсюда
Базовая установка модуля описана - здесь
После установки модуля через систему обновления в демо режиме или , купив, используя купон, необходимо добавить папку api в корне сайта, можно назвать иначе и изменить соответствующие настройки инициализации.
/ - корень сайта
/api/ - директория для обработчиков
/api/index.php -централизованный обработчик, который обрабатывает все методы
/api/.htaccess - файл для предотвращения просмотра всей иерархии
/api/sale/ - группа методов для работы с магазином, например sale.abb2Basket, sale.setQuantity и тп.
/api/sale/add2_basket.php - обработчик метода sale.add2Basket
/api/sale/set_quantity.php - обработчик метода sale.setQuantity
/api/.. - и так далее, любые какие захотите группы и методы
Допустим что вы решили разместить свое API по адресу /api/
относительно корня ( соответственно директория в корне сайта - /api/
). В этой папке необходимо создать индексный файл - index.php
с вызовом модуля.
<?
define('STOP_STATISTICS', true);
define('NO_KEEP_STATISTIC', 'Y');
define('NO_AGENT_STATISTIC', 'Y');
define('DisableEventsCheck', true);
define('BX_SECURITY_SHOW_MESSAGE', true);
define('NOT_CHECK_PERMISSIONS', true);
require_once($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/prolog_before.php');
if(\Bitrix\Main\Loader::includeModule('bxmaker.api'))
{
$oApi = \Bxmaker\Api\Handler::getInstance();
/* если директория не /api/, а например /ajax/,
необходимо указать директорию явно, так -
$oApi->setCurDir(dirname(__FILE__)); */
$oApi->setParam(array(
'IBLOCK_ID_CATALOG' => 2,
));
$oApi->init();
$oApi->showResult();
}
else
{
echo json_encode(array('ststus' => 0, 'error' => array(
'error_code' => 0,
'error_msg' => 'Модуль обработки запросов не установлен'
)));
}
После этого создать файл .htaccess
со следующим текстом
Options -Indexes
После этого можно добавлять уже обработчики для методов запроса. Например нам нужен метод, для добавления товара в корзину. логично его вывести в группу sale
.
Таким образом чтобы указывать в запросе значение для параметра method = sale.add2Basket
, необходимо создать папку sale и файл add2_basket.php
.
Если в методе присутствует точка, то это будет означать наличие группы запросов, соответственно для группы запросов отводится отдельная дирректория относительна корня обработчика запросов.
К примеру:
method = sale.basket.add
, путь до файла будет таким - /api/sale/basket/add.php
method = user.login
, путь до файла - /api/user/login.php
Если в значении метода присутствуют большие буквы, то они будут заменены на символ "_" и прописной аналог, например:
method = user.loginByPhone
, путь до файла - /api/user/login_by_phone.php
method = sale.basket.setQuantity
, путь до файла - /api/sale/basket/set_quantity.php
В таком случае необходимо добавить обработчик этого метода, файл должен находиться по этому пути /api/sale/add2_basket.php
и иметь примерно следующий код:
<?if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) {
die();
}
if (!$this->get('product_id') || intval($this->get('product_id')) <= 0) {
$this->setError('Не удалось определить идентификатор товара!', '1');
return false;
}
$quantity = max(1, intval($this->get('quantity')));
CModule::IncludeModule('iblock');
CModule::IncludeModule('catalog');
CModule::IncludeModule('sale');
$arFields = array();
$dbr = CIBlockElement::GetList(array(), array(
'IBLOCK_ID' => $this->getParam('IBLOCK_ID_CATALOG'), //здесь мы используем параметр указаны при инициализации модуля
'ID' => intval($this->get('product_id'))
), false, array('nPageSize' => 1), array('*'));
if ($ob = $dbr->GetNextElement()) {
$arFields = $ob->GetFields();
$arFields['PROPERTIES'] = $ob->GetProperties();
Add2BasketByProductID($arFields['ID'], $quantity);
// тут можно еще посчитать количество товаров в корзине и их стоимость
$this->setResult(array(
'msg' => 'Товар успешно добавлен в корзину',
'basket' => array(),
'quantity' => $quantity,
'price' => $price,
'price_format' => number_format($price, 0, '.', ' ')
));
}
else {
$this->setError('Не удалось найти товар');
return false;
}
После этого можно например используя jQuery делать AJAX запросы вида:
$.ajax({
url: '/api/',
type: 'POST',
dataType: 'json',
data: {
sessid: BX.bitrix_sessid(),
method: 'sale.add2Basket',
product_id: btn.attr('data-product-id'),
quantity: (isNaN(q) ? 1 : q)
},
error: function (r) {
btn.removeClass('preloader');
},
success: function (r) {
if (!!r.response) {
btn.text('В корзине');
$(document).trigger('changeBasket', r.response.basket);
}
else if (!!r.error) {
console.log('error', r.error.error_msg);
}
}
});
Модуль обрабатывает помимо обычных POST запросов с перечислением параметров и их значений, еще и вариант отправки JSON
строки, когда данные уже закодированы и имеют кодировку UTF-8
.
Пример запросов к серверу в этом формате
$oHttp = new \Bitrix\Main\Web\HttpClient();
$oHttp->setHeader('Content-Type', 'application/json; charset=utf-8');
// идентификатор сессии можно передать в заголовке запроса
$oHttp->setHeader('X-Csrf-Token', 'значение идентификтаора сессии');
$arParams = array(
'method' => 'user.state',
'sessid' => 'значение идентификтаора сессии', // в теле зарпоса или в заголовке
);
$result = $oHttp->post('http://localhost/api/', json_encode($arParams));
echo '<pre>';
print_r($result);
echo '</pre>';
// на примере axios, для jQuery, fetch - подобно, пример в инете можно найти
axios({
url : '/api/',
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
data: JSON.stringify({
method: 'lk.auth.checkCode',
sessid: 'sessid',
phone: '79991112233',
code: '1111'
})
}).then(result => { console.log('result', result)});
В результате работы модуля будет возвращен ответ, который в случае успешного результат вернет объект response
, иначе error
в формате JSON
.
/* в случае успешного выполнения операции */
{
"response" : {
"msg" : "Товар успешно добавлен в корзину"
}
}
{
"error": {
"msg": "Ваша сессия закончилась, обновите страницу и попробуйте снова.",
"code": "/api/1",
"more": []
}
}