Magento provides a handy web services API for integration with other software systems, and it can be extended if you need it to do something that it doesn't do by default. However, incorrectly overriding core Magento code can cause incompatibilities when applying upgrades. The following is an example of how to extend the API in a way that attempts to avoid introducing problems with future releases.
First of all, you need to find the Magento core file that provides the API method you want to extend. These are generally in model files called Api.php or under directories called Api. For example, I recently needed to look up customer orders by their IDs, as opposed to their increment IDs (aka their order numbers, such as '#100000003'). After some searching, I found the file that contains the relevant code at app/code/core/Mage/Sales/Model/Order/Api.php, in the _initOrder() method:
protected function _initOrder($orderIncrementId) { $order = Mage::getModel('sales/order'); /* @var $order Mage_Sales_Model_Order */ $order->loadByIncrementId($orderIncrementId); if (!$order->getId()) { $this->_fault('not_exists'); } return $order; }
To override this, we could put a copy of the file in app/code/local, but that would mean copying the whole file and effectively overriding all the methods in it. Unfortunately this approach can be problematic when upgrading, since other modules may depend on new methods in the API model that aren't available due to the override. A better approach would be to only modify the function we are interested in. Create a file called Example_Webservices.xml in app/etc/modules, containing:
<?xml version="1.0"?> <config> <modules> <Example_Webservices> <active>true</active> <codePool>local</codePool> </Example_Webservices> </modules> </config>
Create the directory app/code/local/Example/Webservices/etc, and create a file called config.xml containing:
<?xml version="1.0"?> <config> <global> <models> <sales> <rewrite> <order_api>Example_Webservices_Model_Sales_Order_Api</order_api> </rewrite> </sales> </models> </global> </config>
This is the usual code for overriding a model. We're rewriting all requests for the Mage_Sales_Model_Order_Api class to our own Example_Webservices_Model_Sales_Order_Api class.
Finally, we need to actually create our model and override the method we're interested in. Create app/code/local/Example/Webservices/Model/Sales/Order/Api.php containing:
class Example_Webservices_Model_Sales_Order_Api extends Mage_Sales_Model_Order_Api { protected function _initOrder($orderIncrementId) { $order = Mage::getModel('sales/order'); if(is_string($orderIncrementId)) { $order->loadByIncrementId($orderIncrementId); if (!$order->getId()) { $this->_fault('not_exists'); } } else { $order->load($orderIncrementId); if (!$order->getId()) { $this->_fault('not_exists'); } } return $order; } }
This class overrides the original model class we're overriding - this way, we only change the specific methods we want to change and minimise the chance of interfering with an upgrade. The modifications to the body of the method are quite simple. Instead of always loading by increment ID, we first check if the $orderIncrementId parameter we are passed is a string. If it's a string, we do an increment ID lookup; if not, we assume it's an ID and look up on that. This works in a similar way to products, where you can use the API to get a product by either ID or SKU.
If your Magento store needs to work with another application in a way that Magento doesn't support, this simple example shows how easy it is to extend Magento's web services API's to allow you to achieve the integration that you require.

Comments
Hi! This seems exactly what i have been looking for... But how can you call it? Can you call it like methods inside magento web service api? I mean would something like this work outside magento:
Peter, this is a great tutorial - in fact, all the Fontis tutorials are great ;)
This approach works great when you're extending an existing API - but let's say that we want to create an API from scratch ...
In our case we're building a custom extension to handle task management for different users inside Magento's Admin. We have API integration (sales orders, invoices, shipments) within our accounting system (Microsoft Dynamics NAV) already but we want to create a button in NAV to notify someone in Magento that there is a problem with an order by creating a task through a new API to our custom extension.
I can't find documentation on creating a new API for our tasks extension - only on how to extend existing APIs. Can you give me any direction?
Darren.
Post new comment