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
- Блоки: 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 для Gooogle 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, то будет возращён результат его работы.