Magento 1.9 REST API – No Response from POST to Custom Route

apijsonmagento-1.9post-datarest

I set up a working custom route for Magento's REST Api.

It works fine for GET requests, as the _retrieve() function of the corresponding V1.php class is being called as expected and returns the data. But now I'm trying to handle POST requests and that's when Magento is behaving weird:

  • When you want to post data you have to define the data as a collection instead of an entity in etc/api2.xml like this: <action_type>collection</action_type>. Otherwise Magento will throw this error in Mage_Api2_Model_Resource (line 207):
// Creation of objects is possible only when working with collection
$this->_critical(self::RESOURCE_METHOD_NOT_IMPLEMENTED);

So when I define the action_type as collection, then the _multiCreate() function of the corresponding V1.php is being called as expected.

  • However Magento now doesn't let me return any data. I want to return this array in JSON format:

    $response = array("success"=>true, "error"=>"", "model"=>array(1,2,3));

'success', 'error' and 'model' are defined as attributes in the api2.xml and should therefore be available. But when I return $response, the response is empty with
Status 207 … Hmmm! Now since it has action_type collection, I have also tried to return the $response wrapped inside another array, but without success.

In my final tryouts I figured out that by setting data with the method $this->getResponse()->addMessage(....) I am able to retrieve data, but I don't think that this is the correct way as it is thought to be for success/error/warning message types and it doesn't fit my data type requirements.

Last but not least I also tried to return data by using the $this->getResponse()->setBody($result) and $this->getResponse()->setRawBody($result) methods, but again – no success:

So Magento experts – What is the correct way to retrieve data from a POST request to the REST Api? I desperately need your help!!

Here's my 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>

Best Answer

If you take a look at class Mage_Api2_Model_Resource which should be extended by your class, you can find function _render().

By examining dispach() function of this class, you can see, that _render() function is called by retrieve operations. So you can use this function at the end of your action like so $this->_render($data).

This function is not used by create operations, which only set Location header to newly created resource url.

To take an advantage of attribute filtering, use $this->getFilter()->out($data) before $this->_render($data)

Mage_Api2_Model_Resource::dispatch() can answer a lot of questions regarding magento REST!

Related Topic