REST API¶
Обзор¶
- cледует модели RESTfull;
 - aвторизация Basic HTTP (логин — email; пароль — API Key из профиля пользователя);
 - вложенность объектов не более 2х (
products/features,products/options,products/features/images); - привилегии групп пользователей, а также привязка к ним определяется в самих объектах.
 
Примечание
Рекомендуем статью о важных аспектах RESTful API.
Список сущностей REST API¶
- Список сущностей REST API
- Товары: products
 - Характеристики товаров: features
 - Опции товаров: options
 - Комбинации опций: combinations
 - Разрешенные/запрещенные комбинации опций: exceptions
 - Вариации: product_variations
 - Группы вариаций: product_variations_groups
 - Блоки: blocks
 - Заявки на обратный звонок: call_requests
 - Незавершенные покупки: carts
 - Категории: categories
 - Комментарии и отзывы: discussions
 - Заказы: orders
 - Страницы: pages
 - Способы оплаты: payments
 - Настройки: settings
 - Способы доставки: shippings
 - Статусы заказов: statuses
 - Витрины: stores
 - Налоги: taxes
 - Пользователи: users
 
 
Что такое REST¶
REpresentational State Transfer (REST) — передача представлений состояний. Стиль построения архитектуры распределенного приложения. Был описан и популяризован в 2000 году Роем Филдингом (Roy Fielding), одним из создателей протокола HTTP.
Суть реализации RESTful API — это представление логики работы магазина в виде набора объектов(сущностей) с изменяемым состоянием. Средство реализации — протокол HTTP 1.1, его методы, статусы, заголовки.
Для изменения состояния объекта используется 4 метода:
- GET — Получение информации об объекте
 - POST — Создание нового объекта
 - PUT — Обновление информации об объекте
 - DELETE — Удаление объекта
 
Исходя из того, что REST архитектура подразумевает работу с логикой в виде работы с состоянием объектов, объекты API не всегда будут соответствовать объектам модели, используемым в магазине.
Яркий пример — реализация добавления товаров в корзину. Для этого в концепции REST следует создать новый объект /cart, и PUT-запрос на этот объект с указанием в параметрах id товара и будет как раз добавлением товара в корзину. При этом как такового не существует объекта “корзина” в модели магазина.
Работа с API¶
В качесте адреса во всех примерах используется example.com. Следует заменять на адрес вашего магазина.
Авторизация¶
Для авторизации используется механизм Basic HTTP.
В качестве имени пользователя выступает адрес электронной почты, в качестве пароля — API-ключ, который задаётся в профиле пользоваеля в Панели администратора магазина.
Примечание
В случе передачи email в строке URL следует знак @, заменить на %40.
Тестирование c помощью REST-клиентов (cURL)¶
cURL позволяет выполнять любые HTTP методы для нужного ресурса. Можно передавать любые параметры запросов и заголовков, а также проверять ответные заголовки и данные. Инструмент коммандной строки «curl», стандартен для большинства *nix систем. Для пользователей Windows подойдёт MinGW/MSYS.
Примечание
Можно использовать другие REST-клиенты, например, Postman для Google Chrome.
Пример использования и базовые опции¶
curl -X PUT www.example.com/api/entity/1 -d "some=var" -d "other=var2" -H "Accept: text/json" -I
- -X 
[METHOD]определяет HTTP метод. - -d 
"name=value"устанавливает имя и значения переменных в POST/PUT. - -H 
[HEADER]устанавливает заголовок. - -I отображает заголовки ответа.
 
Передача в строке URL:
curl --basic -X GET 'http://admin%40example.com:va1t900b3P2UCQWDHZk1MKB83963z16i@example.com/api/users/'
Использование параметра --user:
curl --user admin@example.com:va1t900b3P2UCQWDHZk1MKB83963z16i  -X GET 'http://example.com/api/users/'
Через заголовок --header:
curl --header 'Authorization: Basic YWRtaW5AZXhhbXBsZS5jb206dmExdDkwMGIzUDJVQ1FXREhaazFNS0I4Mzk2M3oxNmk=' -X GET 'http://example.com/api/users/'
В заголовке пара логина/пароля должна быть зашифрована по base64. Вот эти строки иллюстрируют, как это происходит:
$token = base64_encode("yourApiUserName:yourAPIToken");
$authHeaderString = 'Authorization: Basic ' . $token;
Формат выходных данных¶
Нужно установить заголовок Accept. По умолчанию даные возвращаются в JSON:
curl --header "Accept: application/json"
Формат входных данных¶
Нужно установить заголовок Content-type. По умолчанию ожидаются в text/plain:
curl --header "Content-type: application/json"
Архитектура¶
Диаграмма классов¶
Процесс обработки запроса на примере GET¶
Точка входа¶
Файл api.php — точка входа в REST API.
URL для обращения к API:
http://example.com/api.php?_d=products http://example.com/api.php?_d=products/1
При включенном mod_rewrite:
http://example.com/api/products http://example.com/api/products/1
Правило преобразования срабатывает только тогда, когда в пути сразу есть /api.
Форматы ввода/вывода¶
Форматы отвечают за преобразование данных из строки запроса в массив и наоборот из массива в строку ответа.
Определяется это заголовками HTTP запроса.
- ContentType — формат, в котором пришли данные;
 - Accept — формат, в котором данные нужно вернуть.
 
За преобразования отвечает класс Api\FormatManager. Он является синглтоном, при инициализации ему нужно передать классы обработчиков, которые доступны. Каждый обработчик формата должен реализовать интерфейс Api\IFormat. Два метода в нём отвечают за преобразование данных, а getMimeTypes в виде массива возвращает список MIME типов которые может обработать этот класс.
Доступные форматы:
Api\Formats\Json— JSON;Api\Formats\Text— Plain Text.
Объекты REST¶
Ключевая единица модели REST — это объекты, в нашем случае будем называть их сущности. Для работы с ними используется классы унаследованные от абстрактного Api\AEntity.
Каждая сущность должна обязательно реализовывать 4 базовых метода соотвествеющих HTTP.
Для получения списка обектов, либо одного, если указан
$id, параметры для фильтрации придут в$params:abstract public function index($id = '', $params = array());
Для создания объекта. Свойства объекта придут в
$params. В случае пусого массива свойств, либо наличия идентификатора объекта в адресе, запрос автоматически будет сформирован со статусомSTATUS_METHOD_NOT_ALLOWEDи отправлен до выова этого метода.В случае успеха метод должен возвращать статус
STATUS_CREATED:abstract public function create($params);
Для обновления объекта. Cвойства объекта придут в
$params. Идентифиактор в$id. В случае пусого массива свойств, либо пустого идентификатора объекта в адресе, запрос автоматически будет сформирован со статусомSTATUS_METHOD_NOT_ALLOWEDи отправлен до вызова этого метода:abstract public function update($id, $params);
Для удаления объекта. Идентифиактор придёт в
$id. В случае пустого идентификатора объекта в адресе, запрос автоматически будет сформирован со статусомSTATUS_METHOD_NOT_ALLOWEDи отправлен до вызова этого метода.В случае успеха метод должен возвращать статус
STATUS_NO_CONTENT:abstract public function delete($id);
Привилегии¶
Используются привилегии, которые назначаются группам пользователей, в которых в свою очередь состоит тот пользователь, который обращается к API.
Привязка к привилегиям осуществляется посредством указания в классе сущности соответствия названий привилегий методам класса. На примере Api\Entities\Users:
public function privileges()
{
    return array(
        'create' => 'manage_users',
        'update' => 'manage_users',
        'delete' => 'manage_users',
        'index'  => 'view_users'
    );
}
Создание, обновлнение и удаление — это manage_users, просмотр — view_users.
Вложенные сущности¶
Примечание
Пример вложенной сущности — Categories/Products.
Связи “многие ко многим” быть не может. Это ограниение введено специально для исключения путаницы. Считается, что в магазине большая часть объектов устроена так, что один объект будет более зависим от другого. Например, в случае с категориями и товарами это категории, потому что они являются “контейнером” для товаров.
Связь реализуется таким образом. В родителя добавляется функция возвращающая названия её дочерних сущностей:
public function childEntities()
{
    return array(
        'products'
    );
}
После этого все запросы вида /родитель/:id_родителя/потомок, обрабатываются так (на примере categories/3/products):
- выделяются оба объекта из пути, 
idродителя обязателен; - создаётся объект родителя;
 - вызывается метод родителя 
indexс параметромidдля получения данных о родительской сущности; - если статус, возвращённый методом 
indexродителя 200 (STATUS_OK), то данные передаются в потомка и вызывается соответствующий HTTP метод потомка. В нём уже доступны данные о родителе, в качестве возвращаемого значения будет результат его работы; - если статус, возвращённый методом 
indexродителя не 200, то будет возращён результат его работы.