Нет ответа от POST к пользовательскому маршруту REST Api
-
12-12-2019 - |
Вопрос
Я настроил работающий пользовательский маршрут для REST Api Magento.
Это отлично работает для запросов GET, так как _retrieve()
функция соответствующего V1.php
класс вызывается, как и ожидалось, и возвращает данные.Но теперь я пытаюсь обрабатывать POST-запросы, и именно тогда Magento ведет себя странно:
- Когда вы хотите опубликовать данные, вы должны определить данные как коллекцию, а не как объект в
etc/api2.xml
вот так:<action_type>collection</action_type>
.В противном случае Magento выдаст эту ошибку вMage_Api2_Model_Resource
(строка 207):
// Creation of objects is possible only when working with collection
$this->_critical(self::RESOURCE_METHOD_NOT_IMPLEMENTED);
Итак, когда я определяю action_type как коллекцию, то _multiCreate()
функция соответствующего V1.php
вызывается, как и ожидалось.
Однако Magento теперь не позволяет мне возвращать какие-либо данные.Я хочу вернуть этот массив в формате JSON:
$response = array("success"=>true, "error"=>"", "model"=>array(1,2,3));
"успех", "ошибка" и "модель" определены как атрибуты в api2.xml и поэтому должны быть доступны.Но когда я вернусь $response
, ответ пустой с
Статусом 207 ...Хммм!Теперь, поскольку у него есть коллекция action_type, я также попытался вернуть $response
завернутый в другой массив, но безуспешно.
В моих последних испытаниях я выяснил это, установив данные с помощью метода $this->getResponse()->addMessage(....)
Я могу извлекать данные, но я не думаю, что это правильный способ, поскольку считается, что это относится к типам сообщений success / error / warning, и это не соответствует моим требованиям к типу данных.
И последнее, но не менее важное: я также попытался вернуть данные, используя $this->getResponse()->setBody($result)
и $this->getResponse()->setRawBody($result)
методы, но опять же - безуспешно:
Итак, эксперты Magento - каков правильный способ извлечения данных из POST-запроса к REST Api?Мне отчаянно нужна ваша помощь!!
Вот мой api2.xml
:
<customer_login translate="title" module="Test_Restapi">
<group>restapi</group>
<model>restapi/api2_customer_login</model>
<title>Blablabla</title>
<sort_order>10</sort_order>
<privileges>
<customer>
<create>1</create>
<update>1</update>
<retrieve>1</retrieve>
</customer>
<guest>
<create>1</create>
<update>1</update>
<retrieve>1</retrieve>
</guest>
</privileges>
<attributes>
<success>Success</success>
<error>Error</error>
<model>Model</model>
</attributes>
<routes>
<route_collection>
<route>/restapi/customer/login</route>
<action_type>collection</action_type>
</route_collection>
</routes>
<versions>1</versions>
</customer_login>
Решение
Если вы взглянете на класс Mage_Api2_Model_Resource
который должен быть расширен вашим классом, вы можете найти функцию _render()
.
Изучая dispach()
функции этого класса, вы можете видеть, что _render()
функция вызывается с помощью операций извлечения.Таким образом, вы можете использовать эту функцию в конце вашего действия следующим образом $this->_render($data)
.
Эта функция не используется операциями создания, которые только устанавливают заголовок местоположения на вновь созданный URL ресурса.
Чтобы воспользоваться преимуществами фильтрации по атрибутам, используйте $this->getFilter()->out($data)
до того, как $this->_render($data)
Mage_Api2_Model_Resource::dispatch()
могу ответить на множество вопросов, касающихся magento REST!
Другие советы
Мне удалось получить данные из _createMulti()
действуйте, следуя советам @raivis.krumins.Внутри dispatch()
функция системы Mage_Api2_Model_Resource
класс I добавил эти 3 строки после строки 228 в конце if
оператор, в котором задается заголовок location:
$retrievedData = $this->_createMulti($filteredData);
$returnData = $this->getFilter()->out($retrievedData);
$this->_render($returnData);
Первая строка извлекает результат из функции, вторая строка отфильтровывает нежелательные атрибуты (те, которые не заданы в api2.xml
) и, наконец, третья строка возвращает данные в ответе.
Пожалуйста, обратите внимание, что эти изменения всегда должны вноситься в пользовательский модуль.Никогда не меняйте базовый класс!
Непосредственно перед повторным запуском в вашем пользовательском модуле устанавливается функция
$this->GetResponse()-> appendBody(json_encode($response));