Нет ответа от POST на пользовательский маршрут REST Api
Я настроил рабочий пользовательский маршрут для REST Api Magento.
Он отлично работает для запросов GET, так как функция _retrieve()
соответствующего класса V1.php
вызывается должным образом и возвращает данные. Но теперь я пытаюсь обрабатывать запросы на публикацию, и именно тогда 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(....)
, я могу извлекать данные, но я не думаю, что это правильный способ, поскольку считается, что это для типов сообщений об успехе/ошибке/предупреждении, и это не соответствует моим требованиям к типу данных.
И последнее, но не менее важное, я также пытался возвращайте данные с помощью методов $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>
3 answers
Если вы посмотрите на класс 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
я добавил эти 3 строки после строки 228 в конце инструкции if
, где задается заголовок местоположения:
$retrievedData = $this->_createMulti($filteredData);
$returnData = $this->getFilter()->out($retrievedData);
$this->_render($returnData);
Первая строка извлекает результат из функции, вторая строка отфильтровывает нежелательные атрибуты (те, которые не заданы в api2.xml
) и, наконец, третья строка возвращает данные в ответе.
Пожалуйста, обратите внимание, что эти изменения всегда должны вноситься в пользовательский модуль. Никогда не меняйте основной класс!
Непосредственно перед повторным запуском в наборе функций пользовательского модуля
$this->GetResponse()->Тело приложения(json_encode($ответ));