Using Magento API to get Products

Adam Moss picture Adam Moss · Jan 9, 2012 · Viewed 14.6k times · Source

I'm using the Magento API to get product data for products from a certain category from another domain. I have made the API call etc... The code I'm currently using to get the product data looks like this:

$productList = $client->call($session, 'catalog_category.assignedProducts', 7);

foreach ($productList as $product){
    $theProduct = array();
    $theProduct['info'] = $client->call($session, 'catalog_product.info', $product['sku']);
    $allProducts[] = $theProduct;
}

The code works fine, but it goes extremely slow. When I add the image call to the loop it takes about 50 seconds for the page to load, and that's for a site with only 5 products. What I want to know is the following:

  1. Is the code above correct and it's just Magento's API script is very slow?
  2. Is the code above not the best way of doing what I need?
  3. Could there be any other factors making this go so slow?

Any help would be much appreciated. At least if I know I'm using the code right I can look at other avenues.

Thanks in advance!

================= EDIT =================

Using multicall suggested by Matthias Zeis, the data arrives much quicker. Here's the code I used:

$apicalls = array();
$i = 0;
$productList = $client->call($session, 'catalog_category.assignedProducts', 7);

foreach ($productList as $product){
$apicalls[$i] = array('catalog_product.info', $product['product_id']);
$i++;
}

$list = $client->multiCall($session, $apicalls);

This now works much quicker than before! The next issue I've found is that the catalog_product_attribute_media.list call doesn't seem to work in the same way, even though the products all have images set.

The error I'm getting in the var_dump is:

Requested image not exists in product images' gallery.

Anybody know why this may now be happening? Thanks again in advance.

Answer

Matthias Zeis picture Matthias Zeis · Jan 9, 2012

1. Is the code above correct and it's just Magento's API script is very slow?

Your code is correct, but the script is slow because (a) the SOAP API is not blazingly fast and (b) you are doing seperate calls for every single product.

2. Is the code above not the best way of doing what I need?

If you use the SOAP v1 API or XML-RPC, you can test multiCall. At first, call catalog_category.assignedProducts to fetch the product ids. Collect the product ids and execute a multiCall call. That should cut the waiting time down quite a bit.

Unfortunately, Magento doesn't provide a nice solution out of the box to deliver the data like you need it. I recommend that you implement your own custom API call.

Use a product collection model:

$collection = Mage::getModel('catalog/product')->getCollection();

This will get you a Mage_Catalog_Model_Resource_Product_Collection object which can be used to filter, sort, paginate, ... your product list. Iterate over the collection and build an array containing the data you need. You also can generate thumbnails for your products directly while building the data array:

foreach ($products as $product) {
    $data[$product->getSku()] = array(
        /* the attributes no need ... */
        'small_image'   => Mage::helper('catalog/image')->init($product, 'image')
                                ->constrainOnly(true)
                                ->keepAspectRatio(true)
                                ->keepFrame(false)
                                ->resize(100,150)
                                ->__toString(),
        /* some more attributes ... */
    );
}

This should give you quite a performance improvement.

But of course this only is the tip of the iceberg. If this solution is not fast enough for you, avoid SOAP and bypass a part of the Magento stack by building your own API. This doesn't have to be a complex solution: it could be a simple PHP script with HTTP Basic Authentication which parses the URL for filter criteria etc., includes app/Mage.php and calls Mage::app() to initialise the Magento framework. The benefit is that you have the comfort of using Magento classes but you don't have to go through the whole routing process.

Not to forget, you may cache the results because I could imagine that you will show the same products to quite a few visitors on the other domain. Even caching for a few minutes may help your server.

3. Could there be any other factors making this go so slow?

There may be some reasons why the calls are that slow on your server - but without knowing the volume of your data, your server hardware and the customisations you have done, even a best guess won't be that good.