If you are in the business of developing a mobile application or external web/desktop or some other application/service that needs to communicate with Magento trough its API, then my friend you are out of luck. I am not going to say Magento API is a trash, I’ll simply say it massively lacks certain methods within the existing exposed classes that will make your external application usable.
Its all about simple things, right? Well, here is one bottom line simple thing I would like to do with my Magento API. I would like to get a list of all available websites, stores and store views. Can I do that with the latest (as of this writing, 1.4.1.1) Magento? No I cannot! Can I get a list of … etc. For any serious scenario you will most likely be out of luck. What’s interesting is that rarely even a combination of several method calls will give you what you might need. Trust me on this one, I am writing Android application for Magento and its killing me.
So, how do we improve Magento API? That’s easy, I say lets override it enabling the further use all existing method calls while adding new methods to the same classes plus we can throw in some new classes to the API.
We will do so in the form of new extension, lets say that the extension name is “Ajzele_Mapy”.
First we will place the Ajzele_Mapy.xml file under the app/etc/modules/Ajzele_Mapy.xml with the content like shown below.
< ?xml version="1.0"?> <config> <modules> <ajzele_mapy> <active>false</active> <codepool>community</codepool> <depends> <mage_api /> </depends> </ajzele_mapy> </modules> </config>
Then we need to create appropriate file/directory structure inside the app/code/community/Ajzele/ folder.
First lets create the app/code/community/Ajzele/Mapy/etc/config.xml file with the content like shown below.
< ?xml version="1.0"?> <config> <modules> <ajzele_mapy> <version>1.0.0.0.0</version> </ajzele_mapy> </modules> <global> <models> <customer> <rewrite> <customer_api>Ajzele_Mapy_Model_Customer_Customer_Api </customer_api> <group_api>Ajzele_Mapy_Model_Customer_Group_Api</group_api> <address_api>Ajzele_Mapy_Model_Customer_Address_Api</address_api> </rewrite> </customer> <directory> <rewrite> <country_api>Ajzele_Mapy_Model_Directory_Country_Api</country_api> <region_api>Ajzele_Mapy_Model_Directory_Region_Api</region_api> </rewrite> </directory> <catalog> <rewrite> <category_api>Ajzele_Mapy_Model_Catalog_Category_Api</category_api> <product_api>Ajzele_Mapy_Model_Catalog_Product_Api</product_api> <product_attribute_api>Ajzele_Mapy_Model_Catalog_Product_Attribute_Api </product_attribute_api> <product_attribute_media_api>Ajzele_Mapy_Model_Catalog_Product_Attribute_Media_Api </product_attribute_media_api> <product_attribute_set_api>Ajzele_Mapy_Model_Catalog_Product_Attribute_Set_Api </product_attribute_set_api> <product_attribute_tierprice_api>Ajzele_Mapy_Model_Catalog_Product_Attribute_Tierprice_Api </product_attribute_tierprice_api> <product_link_api>Ajzele_Mapy_Model_Catalog_Product_Link_Api </product_link_api> <product_type_api>Ajzele_Mapy_Model_Catalog_Product_Type_Api </product_type_api> </rewrite> </catalog> <cataloginventory> <rewrite> <stock_item_api>Ajzele_Mapy_Model_CatalogInventory_Stock_Item_Api </stock_item_api> </rewrite> </cataloginventory> <directory> <rewrite> <country_api>Ajzele_Mapy_Model_Directory_Country_Api</country_api> <region_api>Ajzele_Mapy_Model_Directory_Region_Api</region_api> </rewrite> </directory> <sales> <rewrite> <order_api>Ajzele_Mapy_Model_Sales_Order_Api</order_api> <order_invoice_api>Ajzele_Mapy_Model_Sales_Order_Invoice_Api </order_invoice_api> <order_shipment_api>Ajzele_Mapy_Model_Sales_Order_Shipment_Api </order_shipment_api> </rewrite> </sales> </models> </global> </config>
In the above app/code/community/Ajzele/Mapy/etc/config.xml file you will notice I overridden all (if I did not miss any) of the exposed Magento API classes. For example, definition Ajzele_Mapy_Model_Directory_Country_Api tells the Magento to use Ajzele_Mapy_Model_Directory_Country_Api each time it wishes to use the Mage_Directory_Model_Country_Api class which is exposed to the API.
My appropriate Ajzele_Mapy_Model_Directory_Country_Api class would then have a content like shown below.
< ?php class Ajzele_Mapy_Model_Directory_Country_Api extends Mage_Directory_Model_Country_Api { }
This example merely overrides the Mage_Directory_Model_Country_Api class, not doing anything more at the moment. Now if I would like to add new public method (one that does not exist in the Mage_Directory_Model_Country_Api), then I would (with one extra configuration entry shown below) call that method trough API like “directory_country.myNewMethod”.
In order to do so, I would need to add one more config info to another file called app/code/community/Ajzele/Mapy/etc/api.xml.
<?xml version="1.0"?> <config> <api> <resources> <customer translate="title" module="customer"> <model>customer/customer_api</model> <title>Customer Api</title> <acl>customer</acl> <methods> <!-- Mapy methods here... --> </methods> </customer> <customer_group> <model>customer/group_api</model> <title>Customer's Groups Api</title> <acl>customer</acl> <methods> <!-- Mapy methods here... --> </methods> </customer_group> <customer_address> <model>customer/address_api</model> <title>Customer Address Api</title> <acl>customer/address</acl> <methods> <!-- Mapy methods here... --> </methods> </customer_address> <directory_country translate="title" module="directory"> <model>directory/country_api</model> <title>Country Api</title> <acl>directory/country</acl> <methods> <!-- Mapy methods here... --> </methods> </directory_country> <directory_region translate="title" module="directory"> <model>directory/region_api</model> <title>Region Api</title> <acl>directory/region</acl> <methods> <!-- Mapy methods here... --> </methods> </directory_region> <catalog_category translate="title" module="catalog"> <model>catalog/category_api</model> <title>Category API</title> <acl>catalog/category</acl> <methods></methods> </catalog_category> <catalog_category_attribute translate="title" module="catalog"> <title>Category attributes API</title> <model>catalog/category_attribute_api</model> <acl>catalog/category</acl> <methods></methods> </catalog_category_attribute> <catalog_product translate="title" module="catalog"> <title>Product API</title> <model>catalog/product_api</model> <acl>catalog/product</acl> <methods></methods> </catalog_product> <catalog_product_attribute translate="title" module="catalog"> <title>Product attributes API</title> <model>catalog/product_attribute_api</model> <acl>catalog/product</acl> <methods></methods> </catalog_product_attribute> <catalog_product_attribute_set translate="title" module="catalog"> <title>Product attribute sets API</title> <model>catalog/product_attribute_set_api</model> <acl>catalog/product</acl> <methods></methods> </catalog_product_attribute_set> <catalog_product_type translate="title" module="catalog"> <title>Product types API</title> <model>catalog/product_type_api</model> <acl>catalog/product</acl> <methods></methods> </catalog_product_type> <catalog_product_attribute_media translate="title" module="catalog"> <title>Product Images API</title> <model>catalog/product_attribute_media_api</model> <acl>catalog/product/media</acl> <methods></methods> </catalog_product_attribute_media> <catalog_product_attribute_tier_price translate="title" module="catalog"> <title>Product Tier Price API</title> <model>catalog/product_attribute_tierprice_api</model> <acl>catalog/product</acl> <methods></methods> </catalog_product_attribute_tier_price> <catalog_product_link translate="title" module="catalog"> <title>Product links API (related, cross sells, up sells)</title> <model>catalog/product_link_api</model> <acl>catalog/product/link</acl> <methods></methods> </catalog_product_link> </resources> <acl> <resources> <customer translate="title" module="customer"> <title>Customers</title> <sort_order>3</sort_order> <!-- Mapy method acl's here... --> </customer> <directory translate="title" module="directory"> <title>Directory</title> <sort_order>5</sort_order> <!-- Mapy method acl's here... --> </directory> <catalog translate="title" module="catalog"> <title>Catalog</title> <sort_order>1</sort_order> </catalog> </resources> </acl> </api> </config>
Careful study of the above file shows how Magento exposes its class and methods to the API. For example, is you open the appcodecoreMageDirectoryetcapi.xml file you will see how it exposes methods for the Directory module.
So, in short, my module merely overrides all the available/exposed API classes enabling you to add new methods or overwrite existing ones in the API. Entire code provided above does not contain any custom methods or does it overwrite any. Its merely an “empty” and “ready” project for writing your own stuff.
I have taken this “extending the Magento API” concept very serious as I will most likely need it for my future Android – Magento apps. With that in mind I have created a repository on the http://github.com/ajzele/mapy (which is empty for now, planning on submitting my first code in a week or so). As you guessed it, the project name is Mapy, short from Magento + API + y to spice up the things .
Hope this article was helpful for you.
Cheers.