Extending Magento web services API v2

Featured Image

In some of previous posts on inchoo.net, colleague of mine – Branko Ajzele wrote about extending Magento API – v1.

Let say that mine extension is called: Inchoo Mapy and I will extend the customer API V2 first.

Although Magento has pretty rich set of API calls, in my project I found that some of the API calls should be extended to fit our project needs. In later posts I will write about that specific needs and possibilities, but now let’s concentrate to extending core API V2 first.

We should take in consideration that if we extend something with same API call name, we are not nice to other installed extensions that use core API too, so we will extend the core API, but let’s add new API calls to not interrupt core API maybe needed by other peoples extensions installed.

Folder structure of extension look like this:

You notice that in extension’s etc/folder I have several files:

config.xml, api.xml, wsdl.xml, wsi.xml

Main config.xml file should look like this:

<?xml version="1.0"?>
 
<config>
    <modules>
        <Inchoo_Mapy>
            <version>0.1.0</version>
        </Inchoo_Mapy>
    </modules>
    <global>
        <models>
            <customer>
                <rewrite>
                    <customer_api_v2>Inchoo_Mapy_Model_Customer_Customer_Api_V2</customer_api_v2>
                </rewrite>
            </customer>
        </models>
    </global>
</config>

After we defined our rewrite(s), let’s create V2.php like you can see in folder structure – in fact, let’s copy V2 file from: core/Mage/Customer/Model/Customer/Api/ and paste it inside our folder structure and make some changes.

For example in this class we will only extend customerCustomerList API V2 call

//Inchoo/Mapy_Model/Customer/Customer/Api/V2.php
 
<?php
 
/**
 * Override for Magento's Customer/Customer API V2
 *
 * @author darko.goles@inchoo.net
 */
class Inchoo_Mapy_Model_Customer_Customer_Api_V2 extends Mage_Customer_Model_Customer_Api_V2 {
 
    public function mapyItems($filters)
    {
	//let's log a message from here
	Mage::log('Hello from extended API call', null, true, 'success.log')
    }
}

We have more steps to do: we need to add our api.xml file inside our etc folder, where our API calls will be defined, and we also have to define two more files: wsdl.xml for soap and wsi.xml to acoomplish possibility for client side to generate client source code from our definitions.

So, let’s copy content of file core/Mage/Customer/etc/api.xml file in our etc folder and edit and remove things that we not need yet for purpose of this article:

<?xml version="1.0"?>
<!-- Inchoo/Mapy/etc/api.xml -->
<config>
    <api>
        <resources>
<!-- START RESOURCES -->
            <!-- START CUSTOMER RESOURCES -->
            <mapy_customer translate="title" module="customer">
                <model>customer/customer_api</model>
                <title>Customer API</title>
                <acl>customer</acl>
                <methods>
                    <list translate="title" module="customer">
                        <title>Retrieve customers paginated list</title>
                        <method>mapyItems/method>
                        <acl>customer/info</acl>
                    </list>
                </methods>
                <faults module="customer">
                    <data_invalid>
                        <code>100</code>
                        <message>Invalid customer data. Details in error message.</message>
                    </data_invalid>
                    <filters_invalid>
                        <code>101</code>
                        <message>Invalid filters specified. Details in error message.</message>
                    </filters_invalid>
                    <not_exists>
                        <code>102</code>
                        <message>Customer not exists.</message>
                    </not_exists>
                    <not_deleted>
                        <code>103</code>
                        <message>Customer not deleted. Details in error message.</message>
                    </not_deleted>
                </faults>
            </mapy_customer>
            <!-- END CUSTOMER RESOURCES -->
<!-- END RESOURCES -->
        </resources>
        <v2>
            <resources_function_prefix>
<!-- START V2 FUNCTIONS PREFIX -->
                    <!-- START V2 CUSTOMER FUNCTION PREFIX -->
                <mapy_customer>mapy_customerCustomer</mapy_customer>
                    <!-- END V2 CUSTOMER FUNCTION PREFIX -->
<!-- END V2 FUNCTIONS PREFIX -->
            </resources_function_prefix>
        </v2>
 
        <acl>
            <resources>
<!-- ACL RESOURCES -->
                <!-- START CUSTOMER ACL RESOURCES -->
                <mapy_customer translate="title" module="customer">
                    <title>Customers</title>
                    <sort_order>3</sort_order>
                    <info translate="title" module="customer">
                        <title>Retrieve customer info</title>
                    </info>
                </mapy_customer>
                <!-- END CUSTOMER ACL RESOURCES -->
<!-- END ACL RESOURCES -->
            </resources>
        </acl>
    </api>
</config>

You will notice that we have V2 node inside api.xml file – that is used as prefix for API V2 calls …
Now just grab the wsdl.xml files and wsi.xml files from core/Mage/Customer/etc and edit them to suit your needs: add new API calls, extend existing complex types definitions etc, and Magento will load and merge all of these files with appropiate core files.

Of course, all API calls is availible at following url:
http://yourmagentoinstallation/api/v2_soap/?wsdl=1

When you are going to auto-generate web service’s client classes, don’t forget inside admin area to change WSI compliance to : yes and reurn to no when you are ready to consume web services.


7 comments

  1. Darko, great post! thank you!

    I’ve tried to get custom attribute using catalogCategoryInfo function in SOAP2 and I got a problem here.

    It exists in Mage_Catalog_Model_Category_Api_V2->info function – I ckecked that. And I added to wsdl.xml into section. But I still cannot get custom attribute. Don’t you know why it doesn’t work?

  2. Brilliant article . I did one by one and it works on Magento Community 1.6 . I did not touch play with WS-I . Only one thing I have twice Customer on Role section ACL. However , I will fix it .

    Thanks a lot for sharing .

  3. Oh, I’ve been extensively working with the API since 1.3 and I’ve gone through many of the problems related to proxy generation with the V2. In fact we have a whole product solely dedicated to the Magento API and we need to support it on a daily basis.

    I was not drawing any conclusions in my comment above except that your last paragraph doesn’t make sense to me.

    You are suggesting to turn on WS-I when auto-generating a proxy and then later turn it off when you want to consume it, right?

    –> This doesn’t work, because the proxy that gets generated from the WS-I enabled mode is _not_ compatible with the V2 in non WS-I mode. There are some differences and you simply can’t interchange a proxy between this two modes.

  4. I suggest you to look into default setting when you install fresh Magento copy. Also, as I know, WSDL is Web services description language and WS-I is just compatibility layer. I strongly suggest you that you first try to implement some client and make some calls with WS-I set to yes/no and then I would be glad to hear your conclusions here. 🙂

  5. Darko, thanks for this post.

    In your last paragraph you’re suggesting to turn of WS-I compliance after the proxy has been generated. Is there any particular reason, why I would want to do so? Without context, this actually sounds pretty bad to me…?

  6. Has anyone managed to get this working on 1.6 community edition? I’m trying to extend the catalog/category api with a new method… I can see the new method in the wsdl but when I try to call it I get an ‘unknown error’ response.

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <blockquote cite=""> <code> <del datetime=""> <em> <s> <strike> <strong>. You may use following syntax for source code: <pre><code>$current = "Inchoo";</code></pre>.