Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

REST API

REST API позволяет другим программам — мобильному приложению, складской системе, сайту на JavaScript — работать с магазином по HTTP и получать ответы в JSON. В Magento для этого не пишут отдельные контроллеры: адрес привязывают к методу интерфейса из папки Api. Репозиторий отзывов для этого уже готов.

Где лежит файл

Адреса REST описывают в файле etc/webapi.xml модуля. Файл создают вручную.

app/code/Acme/Hello/
├── Api/
│   ├── Data/ReviewInterface.php
│   └── ReviewRepositoryInterface.php
└── etc/
    ├── module.xml
    └── webapi.xml              новый файл

Чтение отзыва

<?xml version="1.0"?>
<!-- app/code/Acme/Hello/etc/webapi.xml -->
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">
    <route url="/V1/hello/reviews/:id" method="GET">
        <service class="Acme\Hello\Api\ReviewRepositoryInterface" method="getById"/>
        <resources>
            <resource ref="anonymous"/>
        </resources>
    </route>
</routes>

Запись связывает запрос GET /V1/hello/reviews/5 с методом getById() репозитория. Часть адреса :id попадает в параметр метода с тем же именем.

Выполните bin/magento cache:clean и отправьте запрос:

curl http://shop.test/rest/V1/hello/reviews/1

Ответ — отзыв в JSON: {"id":1,"product_id":1,"author":"Анна","rating":5}. Поля взяты из методов интерфейса ReviewInterface: getProductId() превратился в product_id. Ко всем адресам REST добавляется начало /rest.

Кто может вызывать

Тег resource определяет, кому доступен адрес:

Значение refКому доступно
anonymousВсем без входа
selfВошедшему покупателю, для работы со своими данными
Право из acl.xmlСотруднику или интеграции с этим правом

Создание отзыва

Добавьте в webapi.xml второй адрес, доступный только с правом Acme_Hello::reviews:

<!-- app/code/Acme/Hello/etc/webapi.xml -->
<route url="/V1/hello/reviews" method="POST">
    <service class="Acme\Hello\Api\ReviewRepositoryInterface" method="save"/>
    <resources>
        <resource ref="Acme_Hello::reviews"/>
    </resources>
</route>

Тело запроса — объект JSON, ключи которого совпадают с именами параметров метода. У save() параметр называется $review, поэтому отзыв передают под ключом review.

Запрос с ключом

Защищённые адреса требуют ключ доступа. На локальной копии его проще всего получить по имени и паролю администратора:

curl -X POST http://shop.test/rest/V1/integration/admin/token \
  -H "Content-Type: application/json" \
  -d '{"username": "admin", "password": "Secret123"}'

Ответ — строка с ключом. Её передают в заголовке Authorization:

curl -X POST http://shop.test/rest/V1/hello/reviews \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer КЛЮЧ" \
  -d '{"review": {"product_id": 1, "author": "Мария", "rating": 5}}'

Magento создаст объект ReviewInterface, заполнит его методами setProductId(), setAuthor(), setRating() и передаст в save(). В ответе вернётся сохранённый отзыв с номером. Без заголовка сервер ответит ошибкой 401.

Если включён двухэтапный вход, ключ по паролю не выдаётся. Для постоянных интеграций ключ создают в панели: «Система → Интеграции».

Список адресов

Все адреса REST магазина вместе с вашими показывает встроенная страница документации http://shop.test/swagger. Адреса ядра устроены так же: например, GET /rest/V1/products/24-MB01 вызывает метод get() репозитория товаров.

Частая ошибка

Для метода getList() из урока о репозиториях запрос возвращает пустые объекты. Общий интерфейс SearchResultsInterface не знает, что в списке лежат отзывы. Чтобы отдавать список через REST, создают свой интерфейс результатов поиска в Api/Data, у которого в комментарии к getItems() указан тип \Acme\Hello\Api\Data\ReviewInterface[], — так устроены все репозитории ядра.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.