I'm creating my first custom API and I'm struggling a lot with it. I am not able to call it with v2 API (or use it as a service reference in .NET).
<?php
$host = "127.0.0.1/magento/index.php";
$client = new SoapClient("http://" .$host. "/api/v2_soap?wsdl=1", array('trace' => 1));
$apiuser= "test";
$apikey = "pass";
$data = array(0 => array('date'=>'11-11-2014 10:12:25','operation'=>'PRICES9','successful'=>'0', 'requeue'=>'0'));
try { 
 $sessionId= $client->login($apiuser, $apikey);
$result = array();
$result = $client->syncreportsSyncCreate($sessionId, $data);
 print_r($result);
}
catch (Exception $e){
 echo var_dump($e);
 throw $e;
}
I am getting this error:
" Fatal error: SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://127.0.0.1/magento/index.php/api/v2_soap?wsdl=1' : failed to load external entity"
As far as I understood my custom API wsdl.xml/wsi.xml is not correct.
Can anyone take a look at wsdl.xml/wsi.xml files? Or maybe to tell where I could find correct and working example of custom API?
Here is what I have for now:
Folder structure:
Mycompany
 Syncreports
 etc
 config.xml
 api.xml
 wsi.xml
 wsdl.xml
 Model
 Sync
 Api
 V2.php
 Api.php
/app/code/local/Mycompany/Syncreports/etc/api.xml
<?xml version="1.0" encoding="UTF-8"?>
<config>
 <modules>
 <Mycompany_Syncreports>
 <version>1.0.0</version>
 </Mycompany_Syncreports>
 </modules>
 <api>
 <resources>
 <syncreports_sync translate="title" module="mycompany_syncreports">
 <title>Synchronization API</title>
 <model>syncreports/sync_api</model>
 <acl>syncreports/sync</acl>
 <methods>
 <info translate="title" module="mycompany_syncreports">
 <title>Retrieve synchronization info</title>
 <acl>syncreports/sync/info</acl>
 <method>info</method>
 </info>
 </methods>
 <faults module="mycompany_syncreports">
 <project_not_exists>
 <code>101</code>
 <message>Requested project does not exist.</message>
 </project_not_exists>
 <invalid_data>
 <code>102</code>
 <message>Provided data is invalid.</message>
 </invalid_data>
 <save_error>
 <code>103</code>
 <message>Error while saving project. Details in error message.</message>
 </save_error>
 <remove_error>
 <code>104</code>
 <message>Error while removing project. Details in error message.</message>
 </remove_error>
 </faults>
 </syncreports_sync>
 </resources>
 <resources_alias>
 <sync>syncreports_sync</sync>
 </resources_alias>
 <v2>
 <resources_function_prefix>
 <sync>syncreportsSync</sync>
 </resources_function_prefix>
 </v2>
 <acl>
 <resources>
 <syncreports translate="title" module="mycompany_syncreports">
 <title>SyncReports</title>
 <sync translate="title" module="mycompany_syncreports">
 <title>Synchronization</title>
 <sort_order>110</sort_order>
 <info translate="title" module="mycompany_syncreports">
 <title>Info</title>
 </info>
 </sync>
 </syncreports>
 </resources>
 </acl>
 </api>
</config>
/app/code/local/Mycompany/Syncreports/etc/config.xml
<?xml version="1.0" ?>
<config>
 <modules>
 <Mycompany_Syncreports>
 <version>1.0.0</version>
 </Mycompany_Syncreports>
 </modules>
 <global> 
 <helpers>
 <syncreports>
 <class>Mycompany_Syncreports_Helper</class>
 </syncreports>
 </helpers>
 <models>
 <syncreports>
 <class>Mycompany_Syncreports_Model</class>
 <resourceModel>syncreports_resource</resourceModel>
 </syncreports>
 <syncreports_resource>
 <class>Mycompany_Syncreports_Model_Resource</class>
 <entities>
 <syncreports>
 <table>synchronization_reports</table>
 </syncreports>
 </entities>
 </syncreports_resource>
 </models>
 <resources>
 <syncreports_setup>
 <setup>
 <module>Mycompany_Syncreports</module>
 </setup>
 <connection>
 <use>core_setup</use>
 </connection>
 </syncreports_setup>
 <syncreports_write>
 <connection>
 <use>core_write</use>
 </connection>
 </syncreports_write>
 <syncreports_read>
 <connection>
 <use>core_read</use>
 </connection>
 </syncreports_read>
 </resources>
 </global> 
 <admin>
 <routers>
 <adminhtml>
 <args>
 <modules>
 <syncreports before="Mage_Adminhtml">Mycompany_Syncreports_Adminhtml</syncreports>
 </modules>
 </args>
 </adminhtml>
 </routers>
 </admin>
 <frontend>
 <routers>
 <syncreports>
 <use>standard</use>
 <args>
 <module>Mycompany_Syncreports</module>
 <frontName>syncreports</frontName>
 </args>
 </syncreports>
 </routers>
 </frontend>
 <adminhtml>
 <layout>
 <updates>
 <syncreports>
 <file>syncreports.xml</file>
 </syncreports>
 </updates>
 </layout>
 </adminhtml> 
</config>
/app/code/local/Mycompany/Syncreports/etc/wsi.xml
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:typens="urn:{{var wsdl.name}}"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
 xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
 xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
 name="{{var wsdl.name}}"
 targetNamespace="urn:{{var wsdl.name}}">
 <wsdl:types>
 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:{{var wsdl.name}}">
 <xsd:complexType name="syncreportsSyncItemsEntityArray">
 <xsd:sequence>
 <xsd:element maxOccurs="unbounded" name="complexObjectArray" type="typens:syncreportsSyncItemsEntity" />
 </xsd:sequence>
 </xsd:complexType>
 <xsd:complexType name="syncreportsSyncItemsEntity">
 <xsd:sequence>
 <xsd:element name="date" type="xsd:date" />
 <xsd:element name="operation" type="xsd:string" />
 <xsd:element name="successful" type="xsd:int" />
 <xsd:element name="requeue" type="xsd:int" />
 </xsd:sequence>
 </xsd:complexType>
 <xsd:complexType name="syncreportsSyncCreateEntity">
 <xsd:sequence>
 <xsd:element name="date" type="xsd:date" />
 <xsd:element name="operation" type="xsd:string" />
 <xsd:element name="successful" type="xsd:int" />
 <xsd:element name="requeue" type="xsd:int" />
 </xsd:sequence>
 </xsd:complexType>
 <xsd:element name="syncreportsSyncCreateRequestParam">
 <xsd:complexType>
 <xsd:sequence>
 <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
 <xsd:element minOccurs="1" maxOccurs="1" name="data" type="typens:syncreportsSyncItemsEntity" />
 </xsd:sequence>
 </xsd:complexType>
 </xsd:element>
 <xsd:element name="syncreportsSyncCreateResponseParam">
 <xsd:complexType>
 <xsd:sequence>
 <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:syncreportsSyncItemsEntityArray" />
 </xsd:sequence>
 </xsd:complexType>
 </xsd:element>
 <xsd:element name="syncreportsSyncItemsRequestParam">
 <xsd:complexType>
 <xsd:sequence>
 <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
 <xsd:element minOccurs="1" maxOccurs="1" name="data" type="typens:syncreportsSyncItemsEntity" />
 </xsd:sequence>
 </xsd:complexType>
 </xsd:element>
 <xsd:element name="syncreportsSyncItemsResponseParam">
 <xsd:complexType>
 <xsd:sequence>
 <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:syncreportsSyncItemsEntityArray" />
 </xsd:sequence>
 </xsd:complexType>
 </xsd:element>
 </xsd:schema>
 </wsdl:types>
 <wsdl:message name="syncreportsSyncItemsRequest">
 <wsdl:part name="parameters" element="typens:syncreportsSyncItemsRequestParam" />
 </wsdl:message>
 <wsdl:message name="syncreportsSyncItemsResponse">
 <wsdl:part name="parameters" element="typens:syncreportsSyncItemsResponseParam" />
 </wsdl:message>
 <wsdl:message name="syncreportsSyncCreateRequest">
 <wsdl:part name="parameters" element="typens:syncreportsSyncCreateRequestParam" />
 </wsdl:message>
 <wsdl:message name="syncreportsSyncItemsResponse">
 <wsdl:part name="parameters" element="typens:syncreportsSyncCreateResponseParam" />
 </wsdl:message>
 <wsdl:portType name="{{var wsdl.handler}}PortType">
 <wsdl:operation name="syncreportsSyncItems">
 <wsdl:documentation>Retrieve project info</wsdl:documentation>
 <wsdl:input message="typens:syncreportsSyncItemsRequest" />
 <wsdl:output message="typens:syncreportsSyncItemsResponse" />
 </wsdl:operation>
 </wsdl:portType>
 <wsdl:portType name="{{var wsdl.handler}}PortType">
 <wsdl:operation name="syncreportsSyncCreate">
 <wsdl:documentation>Retrieve project info</wsdl:documentation>
 <wsdl:input message="typens:syncreportsSyncCreateRequest" />
 <wsdl:output message="typens:syncreportsSyncCreateResponse" />
 </wsdl:operation>
 </wsdl:portType>
 <wsdl:binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
 <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
 <wsdl:operation name="syncreportsSyncItems">
 <soap:operation soapAction="" />
 <wsdl:input>
 <soap:body use="literal" />
 </wsdl:input>
 <wsdl:output>
 <soap:body use="literal" />
 </wsdl:output>
 </wsdl:operation>
 <wsdl:operation name="syncreportsSyncCreate">
 <soap:operation soapAction="" />
 <wsdl:input>
 <soap:body use="literal" />
 </wsdl:input>
 <wsdl:output>
 <soap:body use="literal" />
 </wsdl:output>
 </wsdl:operation>
 </wsdl:binding>
 <wsdl:service name="{{var wsdl.name}}Service">
 <wsdl:port name="{{var wsdl.handler}}Port" binding="typens:{{var wsdl.handler}}Binding">
 <soap:address location="{{var wsdl.url}}" />
 </wsdl:port>
 </wsdl:service>
</wsdl:definitions>
/app/code/local/Mycompany/Syncreports/etc/wsdl.xml
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns:typens="urn:{{var wsdl.name}}" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
 xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/"
 name="{{var wsdl.name}}" targetNamespace="urn:{{var wsdl.name}}">
 <types>
 <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:Magento">
 <import namespace="http://schemas.xmlsoap.org/soap/encoding/" schemaLocation="http://schemas.xmlsoap.org/soap/encoding/" />
 <complexType name="syncreportsSyncItemsEntity">
 <all>
 <element name="date" type="xsd:date" minOccurs="1" />
 <element name="operation" type="xsd:string" minOccurs="1" />
 <element name="successful" type="xsd:int" minOccurs="1" />
 <element name="requeue" type="xsd:int" minOccurs="1" />
 </all>
 </complexType>
 <complexType name="syncreportsSyncItemsEntityArray">
 <complexContent>
 <restriction base="soapenc:Array">
 <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:syncreportsSyncItemsEntity[]" />
 </restriction>
 </complexContent>
 </complexType>
 <complexType name="syncreportsSyncCreateEntity">
 <all>
 <element name="date" type="xsd:date" minOccurs="1" />
 <element name="operation" type="xsd:string" minOccurs="1" />
 <element name="successful" type="xsd:int" minOccurs="1" />
 <element name="requeue" type="xsd:int" minOccurs="1" />
 </all>
 </complexType>
 </schema>
 </types>
 <message name="syncreportsSyncItemsRequest">
 <part name="sessionId" type="xsd:string" />
 </message>
 <message name="syncreportsSyncItemsResponse">
 <part name="result" type="typens:syncreportsSyncItemsEntityArray" />
 </message>
 <message name="syncreportsSyncCreateRequest">
 <part name="sessionId" type="xsd:string" />
 <part name="data" type="xsd:syncreportsSyncCreateEntity" />
 </message>
 <message name="syncreportsSyncCreateResponse">
 <part name="result" type="typens:syncreportsSyncCreateEntityArray" />
 </message>
 <portType name="{{var wsdl.handler}}PortType">
 <operation name="syncreportsSyncItems">
 <documentation>Retrieve sync info</documentation>
 <input message="typens:syncreportsSyncItemsRequest" />
 <output message="typens:syncreportsSyncItemsResponse" />
 </operation>
 <operation name="syncreportsSyncCreate">
 <documentation>Retrieve sync info</documentation>
 <input message="typens:syncreportsSyncCreateRequest" />
 <output message="typens:syncreportsSyncCreateResponse" />
 </operation>
 </portType>
 <binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
 <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
 <operation name="syncreportsSyncItems">
 <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
 <input>
 <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
 </input>
 <output>
 <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
 </output>
 </operation>
 <operation name="syncreportsSyncCreate">
 <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
 <input>
 <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
 </input>
 <output>
 <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
 </output>
 </operation>
 </binding>
 <service name="{{var wsdl.name}}Service">
 <port name="{{var wsdl.handler}}Port" binding="typens:{{var wsdl.handler}}Binding">
 <soap:address location="{{var wsdl.url}}" />
 </port>
 </service>
</definitions>
/app/code/local/Mycompany/Syncreports/Model/Sync/Api.php
<?php
 class Mycompany_Syncreports_Model_Sync_Api extends Mage_Api_Model_Resource_Abstract
 {
 public function info($data){
 //some actions with $data object
 return "This is the message: ";
 }
}
/app/code/local/Mycompany/Syncreports/Model/Sync/Api/V2.php
<?php
class Mycompany_Syncreports_Model_Sync_Api_V2 extends Mycompany_Syncreports_Model_Sync_Api{
 public function create($data){
 //some actions with $data object
 return "This is the message: ";
 }
}
- 
 What happens when you load 127.0.0.1/magento/index.php/api/v2_soap?wsdl=1 in a web browser?Alana Storm– Alana Storm2014年02月25日 02:45:51 +00:00Commented Feb 25, 2014 at 2:45
- 
 I'm getting generated wsdl of magento (including methods written by me).intentarr– intentarr2014年02月26日 08:00:28 +00:00Commented Feb 26, 2014 at 8:00
1 Answer 1
I've tested your for WS-I compliance disabled and here are the results.
The wsdl is correct and it (almost) works.
First change this in your config.xml. 
 <helpers>
 <syncreports>
 <class>Mycompany_Syncreports_Helper</class>
 </syncreports>
 </helpers>
To this:
 <helpers>
 <mycompany_syncreports>
 <class>Mycompany_Syncreports_Helper</class>
 </mycompany_syncreports>
 </helpers>
Next: I see that in your api.xml you declared only an info method, but in the wsdl you have 2 other methods syncreportsSyncCreate, syncreportsSyncCreate.
Add those methods to api.xml otherwise you will get an invalid path error message.
 <methods>
 <info translate="title" module="mycompany_syncreports">
 <title>Retrieve synchronization info</title>
 <acl>syncreports/sync/info</acl>
 <method>info</method>
 </info>
 <create translate="title" module="mycompany_syncreports">
 <title>Create synchronization</title>
 <acl>syncreports/sync/create</acl>
 <method>create</method>
 </create>
 <items translate="title" module="mycompany_syncreports">
 <title>List items</title>
 <acl>syncreports/sync/list</acl>
 <method>items</method>
 </items>
 </methods>
Also add the methods to your api model (v2 also if needed).
Now it seams to work.
This is what I send: 
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:Magento">
 <soapenv:Header/>
 <soapenv:Body>
 <urn:syncreportsSyncCreate soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
 <sessionId xsi:type="xsd:string">SESSION KEY HERE</sessionId>
 </urn:syncreportsSyncCreate>
 </soapenv:Body>
</soapenv:Envelope>
This is what I get.
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:Magento" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
 <SOAP-ENV:Body>
 <ns1:syncreportsSyncCreateResponse>
 <result xsi:type="xsd:string">This is the message:</result>
 </ns1:syncreportsSyncCreateResponse>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
So I guess the method works.
When I enable the WS-I compliance I don't get any result from any call. Not even from login. If I find something I will edit the answer. But you can at least test for WS-I compliance off.
[Edit]
I think I found the issue with your wsi file also.
You have declared the type syncreportsSyncItemsResponse twice and the declaration for syncreportsSyncCreateResponse is missing. I assume it was a copy/paste/replace error (you forgot the replace).
Change this:
<wsdl:message name="syncreportsSyncItemsResponse">
 <wsdl:part name="parameters" element="typens:syncreportsSyncCreateResponseParam" />
</wsdl:message>
To this:
<wsdl:message name="syncreportsSyncCreateResponse">
 <wsdl:part name="parameters" element="typens:syncreportsSyncCreateResponseParam" />
</wsdl:message>
A side note...you may also want to change the definition of <xsd:element name="syncreportsSyncCreateResponseParam"> to fit in with the response type of the method. Now you declare that you return an array, but in the end I assume you will return a boolean or a string. 
- 
 Ok, now it works ! I appreciate your answer, thanks for help !intentarr– intentarr2014年02月26日 08:01:19 +00:00Commented Feb 26, 2014 at 8:01