This tutorial is the fourth and final in a series of four tutorials to explain you how you can use SOAP to connect to Magento. In the first three tutorials we have explained the most common tasks you will perform through the API. In this final tutorial you will learn how to make multiple calls at once, how to use alternative SOAP-clients or XML-RPC and some other tips and tricks.
Making multiple calls at once
With the available "list()" methods you can successfuly collect a list of items (products, categories, customers), but further inspection of the returned data will show that it does not include the full item-data. For instance when returning products the "description" is missing.
The logic is here that you can use "list()" to give a full-list of items (or for instance a list based upon filters) but that you will still need the "info()" method to get the full information for every item in that list.
Instead of making a "category_product.info" call for every product in the list (which will cost a lot of extra HTTP-traffic) you can combine multiple call in one SOAP-call through the "multiCall" method. The following is a simple example:
$calls = array(
array( 'catalog_product.info', 166 ),
array( 'catalog_product.info', 167 ),
array( 'catalog_product.info', 168 ),
);
$results = $soap->multiCall( $session_id, $calls );
You can also combine multiple API-methods of different types in the same call:
$calls = array(
array( 'catalog_product.list' ),
array( 'customer.list' ),
array( 'directory_country.list' ),
);
$results = $soap->multiCall( $session_id, $calls );
Caching the API result
The SOAP API is an easy way for connecting Magento to other applications. It also allows for integration between applications which can only connect over the Internet. Besides the security risks this introduces, you should also beware of the performance aspect. Fetching a list of products through SOAP will always take more time then reading the same data from a local database.
Also imagine what would happen if Magento lost its connection to the Internet. Is your client-side application rendered helpless? A better solution to these kinds of problems would be to cache the results received from the API. This caching could be done through some kind of page-caching mechanism, PHP-caching but also just by saving the Magento-data in a temporary database table.
SOAP error handling
When making a wrong call to the Magento API, the result might be an empty array, an integer (to indicate an error for instance) or even a NULL-value. In all cases you want to make sure that the $result you receive is indeed the $result you expect.
Even worse: If a call is missing arguments or is handed over the wrong arguments, the SOAP-client might throw a SoapFault exception and stop the code execution.
$result = $soap->call( $session_id, 'catalog_product.info', 0 );
In this case you want to handle the SoapFault exception yourself:
try {
$result = $soap->call( $session_id, 'catalog_product.info', 0 );
} catch( SoapFault $fault ) {
echo $fault->getMessage();
}
This piece of code will produce the message "Product not exists".
It is important to know that the client as well as the server can throw errors. It is your responsebility to inspect the error and act accordingly.
Using the PEAR::SOAP client
The PEAR::SOAP client works a little bit different then the PHP SOAP client. As the PEAR-client is just a regular PHP-library it needs to be included before the client-object can be instantiated:
require_once 'SOAP/Client.php' ;
$soap = new Soap_Client( $mage_url );
Another big difference is that the SOAP-properties need to be declared explicityly. While with the regular PHP-SOAP client parameters can be in the form of a normal array, with the PEAR-client the usage of an associative array is mandatory:
$arguments = array(
'username' => $mage_user,
'apiKey' => $mage_api_key,
);
$session_id = $soap->call( 'login', $arguments );
Because of this usage of associative arrays the code grows bigger with every API-call:
$arguments = array(
'sessionId' => $session_id,
'resourcePath' => 'catalog_product.list',
'args' => array(),
);
$products = $soap->call( 'call', $arguments );
Using XML-RPC
This document explained a lot about the Magento API but in all examples SOAP was used. Besides communication through SOAP, another option could be to use a XML-RPC client. The Magento API however remains the same: You make through your client (either SOAP or XML-RPC) a call to a specific API-method with or without arguments, and you receive a response.
As for now there is no XML-RPC client available as PHP-extension. The Zend Framework offers a client though, as does PEAR. Here we will show an example with the PEAR XML-RPC client which can be installed with the command "pear install XML_RPC".
As with the PEAR-client for SOAP, we need to include the proper class before we can instantiate the XML-RPC classes:
require_once 'XML/RPC.php' ;
$xmlrpc = new XML_RPC_Client( '/api/xmlrpc', 'magento1.dev', 80 );
You can see that the arguments are bit different: First the path, then the hostname and then the TCP-port the webserver is running on - if you're running Magento on SSL, use port 443 here. The XML_RPC_Client-class determines itself whether HTTP or HTTPS should be used.
The next step is logging in. The important thing you will notice here is that every string or integer needs to be converted into a XML_RPC_Value-object or (in case of the response) converted back into a regular value. Also the call is first wrapped in a XML_RPC_Message before it is actually sent.
$arguments = array(
new XML_RPC_Value( $mage_user, 'string' ),
new XML_RPC_Value( $mage_api_key, 'string' ),
);
$message = new XML_RPC_Message( 'login', $arguments );
$response = $xmlrpc->send( $message );
$session_id = XML_RPC_decode( $response->value() );
Fetchin a list of products is done in more or less the same way:
$arguments = array(
new XML_RPC_Value( $session_id, 'string' ),
new XML_RPC_Value( 'catalog_product.list', 'string' ),
);
$message = new XML_RPC_Message( 'call', $arguments );
$response = $xmlrpc->send( $message );
$products = XML_RPC_decode( $response->value() );
Use your own wrapper-class to extend SoapClient
Because of the complexity of each SOAP-call it might be a wise idea to right your own wrapper-class that extends the functionality of the SoapClient. This class can then be responsible for using $session_id, the proper calling of the right API-methods, detecting whether an API-call failed, check the input, check the output, and so on. Such a class might be used in your application like this:
$products = $MageSoap->getProducts();
Final note
I hope you enjoyed these four tutorials. In the future we plan to post more of these tutorials, so feel free to come back.
About the author
Jisse Reitsma is the founder of Yireo, extension developer, developer trainer and 3x Magento Master. His passion is for technology and open source. And he loves talking as well.