Like in SOAP web services, Magento REST API also offers some kind of filtering results as part of REST web services.

We have several possibilities available as described on the official website.

Let’s show sample REST request made to Magento (without filters):
(Skipping part how we get oAuth token and saved it in session, because it is out of the scope of this article …)

<?php
 
public function getRestDataAction()
    {
        $accessToken = Mage::getSingleton('core/session')->getAccessToken();
        $accessToken = unserialize(base64_decode($accessToken));
 
        if (!$accessToken) {
            echo 'Access Token invalid!';
            return;
        }
 
        $oAuthClient = Mage::getModel('apiworks_restclient/oauth_client');
        $params = $oAuthClient->getConfigFromSession();
 
        //Get REST client object from oAuth token
        $restClient = $accessToken->getHttpClient($params);
 
        // Set REST resource URL
        $restClient->setUri(sprintf('%s/api/rest/orders', $this->_getSiteUrl()));
 
        $restClient->setCookie('XDEBUG_SESSION', 'PHPSTORM');
 
        $restClient->setConfig(array('timeout' => 60));
  
        // In Magento it is neccesary to set json or xml headers in order to work
        $restClient->setHeaders('Accept', 'application/xml');
 
        // Get method
        $restClient->setMethod(Zend_Http_Client::GET);
         
        //Make REST request
        $response = $restClient->request();
         
        // Here we can see that response body contains json list of products
        $this->getResponse()->setBody($response->getBody());
 
        return;
    }

Filtering above order list by customer_id would look like this:

<?php
 
//...
 
    // Set REST resource URL
    $restClient->setUri(sprintf('%s/api/rest/orders', $this->_getSiteUrl()));
 
    $restClient->setParameterGet('filter[0][attribute]', 'customer_id');
    $restClient->setParameterGet('filter[0][eq]', '1');
 
//...

Which will produce the URL:
http://siteurl.com/api/rest/orders?filter[0][attribute]=customer_id&filter[0][eq]=1 and return orders filtered by customer_id = 1.

I traced where Magento is using above filters in code in order to get more information about which attributes are available for specific entity and my search ended up in:
Mage_Api2_Model_Resource around line 724 where all magic with URL parameters is happening:

<?php
 
final protected function _applyCollectionModifiers(Varien_Data_Collection_Db $collection)
    {
        $pageNumber = $this->getRequest()->getPageNumber();
        if ($pageNumber != abs($pageNumber)) {
            $this->_critical(self::RESOURCE_COLLECTION_PAGING_ERROR);
        }
 
        $pageSize = $this->getRequest()->getPageSize();
        if (null == $pageSize) {
            $pageSize = self::PAGE_SIZE_DEFAULT;
        } else {
            if ($pageSize != abs($pageSize) || $pageSize > self::PAGE_SIZE_MAX) {
                $this->_critical(self::RESOURCE_COLLECTION_PAGING_LIMIT_ERROR);
            }
        }
 
        $orderField = $this->getRequest()->getOrderField();
 
        if (null !== $orderField) {
            $operation = Mage_Api2_Model_Resource::OPERATION_ATTRIBUTE_READ;
            if (!is_string($orderField)
                || !array_key_exists($orderField, $this->getAvailableAttributes($this->getUserType(), $operation))
            ) {
                $this->_critical(self::RESOURCE_COLLECTION_ORDERING_ERROR);
            }
            $collection->setOrder($orderField, $this->getRequest()->getOrderDirection());
        }
        $collection->setCurPage($pageNumber)->setPageSize($pageSize);
 
        return $this->_applyFilter($collection);
    }

As we can see, this method is handling custom pagination, sort order from provided URL parameters and finally, filtering of result collection by calling ‘_applyFilter’ method:

<?php
 
    protected function _applyFilter(Varien_Data_Collection_Db $collection)
    {
        $filter = $this->getRequest()->getFilter();
 
        if (!$filter) {
            return $this;
        }
        if (!is_array($filter)) {
            $this->_critical(self::RESOURCE_COLLECTION_FILTERING_ERROR);
        }
        if (method_exists($collection, 'addAttributeToFilter')) {
            $methodName = 'addAttributeToFilter';
        } elseif (method_exists($collection, 'addFieldToFilter')) {
            $methodName = 'addFieldToFilter';
        } else {
            return $this;
        }
        $allowedAttributes = $this->getFilter()->getAllowedAttributes(self::OPERATION_ATTRIBUTE_READ);
 
        foreach ($filter as $filterEntry) {
            if (!is_array($filterEntry)
                || !array_key_exists('attribute', $filterEntry)
                || !in_array($filterEntry['attribute'], $allowedAttributes)
            ) {
                $this->_critical(self::RESOURCE_COLLECTION_FILTERING_ERROR);
            }
            $attributeCode = $filterEntry['attribute'];
 
            unset($filterEntry['attribute']);
 
            try {
                $collection->$methodName($attributeCode, $filterEntry);
            } catch(Exception $e) {
                $this->_critical(self::RESOURCE_COLLECTION_FILTERING_ERROR);
            }
        }
        return $this;
    }

This one is pretty obvious and here is the place where filters are set on collection.

Now we can put Mage::log here and execute some specific REST api call in order to log list of $allowedAttributes for that specific REST resource.

I hope that this article will be helpful.

Cheers.

Categories: Magento

Leave a Reply

Your email address will not be published. Required fields are marked *