Salesforce Integration Tutorial Creating a SOAP Web Service in Apex

As you can see above, we have a method named as:- getContactIdAndNames() which is called when we make a get request to this API. Inside this method, we’re getting the contactLimit i.e. the number of contacts to be queried as a URL parameter and we’re returning a list of contacts in the response.

Creating a custom SOAP API

Now, I am going to convert the same method into a webservice method so that it’s converted into a SOAP API and then we’ll generate a WSDL file for it and call it from SOAP UI client. If you’re not aware of SOAP UI, please have a look at this tutorial first and then you can come back to the current tutorial as we’re going to use SOAP UI client to hit our custom SOAP API and get the response.

Let’s have a look at the updated code below:-

As you can see above, I removed all the annotations like:- @HTTPPost @RestResource etc. as we don’t need them in case of defining a SOAP API. All we need is a global class with a static method defined with webservice keyword. The number of contacts to query that we were giving previously as a URL parameter are now given in the method parameter named as:- contactLimit. After that we’re simply querying the contacts and returning the list of contacts in the response.

And that’s all. You have successfully created a custom SOAP API in Salesforce. SOAP APIs basically support GET and POST HTTP Methods according to the w3 specifications defined here:- https://www.w3.org/TR/2007/REC-soap12-part0-20070427/#L26854 but we mostly use POST in case of SOAP requests as we have messages encoded in XML format. So, whenever you need to create a SOAP webservice in Salesforce, all you need to do is to define a static method in a global class with the keyword webservice. You can take the input as a parameter in method and the data returned by the method will be given in the response.

Generating a WSDL file

Now, it’s time to test our custom SOAP API that will return the contact id and names of contacts present in salesforce and we can limit those contacts by giving the contactLimit in the input request XML. Remember, when we wanted to consume a SOAP API we used WSDL2Apex to generate an apex class from WSDL. In the same way you can generate a WSDL from your custom apex class. All you need to do is go to setup and search for apex classes. Click on Apex Classes under Develop and you’ll see the below page:-

As you can see above in the ContactResource class I have an option of WSDL. Either you can click this or when you open the ContactResource class, you’ll see a Generate WSDL button as shown below:-

On clicking this button you can see another xml which is the WSDL file for our custom SOAP API that we just created. It’ll look similar as you can see below:-

You can provide this XML to the 3rd party who wants to consume your custom SOAP API and it’ll be able to connect with Salesforce.

Testing our SOAP API using SOAP UI

Now we have the WSDL for our custom SOAP API. So, it’s time to test our SOAP API. I have already imported the Enterprise WSDL into the SOAP UI and got the session id. If you want to learn that, you can have a look at another tutorial by clicking here. I am going to add our new WSDL to the existing project. To do that, just right click on the project and click on Add WSDL as shown below:-

You’ll see a dialog as shown below:-

Choose your custom WSDL file and click on OK. When I tried to import the WSDL and clicked on OK button, I got some errors as shown below:-

These errors are coming because the WSDL file that we downloaded from Salesforce has some tags missing. For ex:- The first error is regarding the ChangeEventHeader which is not found in our WSDL file. However, I checked Enterprise WSDL and I was able to find the ChangeEventHeader as shown below:-

The other errors are related to some other type tags like:- json, stringList. You can find all the missing data in the enterprise wsdl and can copy from there to update your actual wsdl file.

I tried and added the ChangeEventHeaderjson, and stringList xml types that were missing in my custom WSDL file below the schema tag as shown below:-

Please note that I have added xsd: namespace also along with the parent tag name for consistency, as all the other tags were having this namespace in the custom xml file I am trying to import. I tried to import my WSDL file in SOAP UI again and found that those 3 errors are resolved and I have some of the remaining errors that I need to resolve.

So, I updated the the custom API xml file again adding the missing contents and tried to import that file again. Finally, I got my XML imported into SOAP UI and our method getContactIdAndNames is available with the input XML request as shown below:-

I am also sharing the XML changes I did below, so that you can just add-on the same elements in your custom XML in case the error is exactly same. Otherwise you’ll find all the missing elements in Enterprise XML from Salesforce.

<xsd:complexType name=”SearchLayoutButtonsDisplayed”>
<xsd:sequence>
<element name=”applicable” type=”xsd:boolean”/>
<element name=”buttons” minOccurs=”0″ maxOccurs=”unbounded” type=”tns:SearchLayoutButton”/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name=”SearchLayoutFieldsDisplayed”>
<xsd:sequence>
<element name=”applicable” type=”xsd:boolean”/>
<element name=”fields” minOccurs=”0″ maxOccurs=”unbounded” type=”tns:SearchLayoutField”/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name=”JunctionIdListNames”>
<xsd:sequence>
<element name=”names” minOccurs=”0″ maxOccurs=”unbounded” type=”xsd:string”/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name=”RelationshipReferenceTo”>
<xsd:sequence>
<element name=”referenceTo” minOccurs=”0″ maxOccurs=”unbounded” type=”xsd:string”/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name=”RecordTypesSupported”>
<xsd:sequence>
<element name=”recordTypeInfos” minOccurs=”0″ maxOccurs=”unbounded” type=”tns:RecordTypeInfo”/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name=”StringList”>
<xsd:sequence>
<element name=”values” type=”xsd:string” minOccurs=”0″ maxOccurs=”unbounded”/>
</xsd:sequence>
</xsd:complexType>
<xsd:simpleType name=”json”>
<xsd:restriction base=”xsd:string”>
<xsd:enumeration value=”json”/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name=”ChangeEventHeader”>
<xsd:sequence>
<element name=”entityName” type=”xsd:string”/>
<element name=”recordIds” type=”xsd:string” minOccurs=”1″ maxOccurs=”unbounded”/>
<element name=”commitTimestamp” type=”xsd:long”/>
<element name=”commitNumber” type=”xsd:long”/>
<element name=”commitUser” type=”xsd:string”/>
<element name=”diffFields” type=”xsd:string” minOccurs=”0″ maxOccurs=”unbounded”/>
<element name=”changeType” type=”tns:changeEventType”/>
<element name=”changeOrigin” type=”xsd:string”/>
<element name=”transactionKey” type=”xsd:string”/>
<element name=”sequenceNumber” type=”xsd:int”/>
<element name=”nulledFields” type=”xsd:string” minOccurs=”0″ maxOccurs=”unbounded”/>
<element name=”changedFields” type=”xsd:string” minOccurs=”0″ maxOccurs=”unbounded”/>
</xsd:sequence>
</xsd:complexType>

view rawCustomWSDLUpdates.xml hosted with ❤ by GitHubNow, It’s time to test our API. As you can see in the image below, I commented out the XML tags that I am not using, added the session id received from login request between the con:sessionId xml tag. Between the con:getContactIdAndNamesTag I have another tag named as con:contactLimit, which is nothing but the parameter of our apex method. I have specified the limit as 2 here as I just want to fetch 2 contacts from my org with Id and Name.

As you can see above, on the left hand side I have the request XML that I sent using the green play button above and on the right hand side, I have the response xml with 2 contacts queried from my Salesforce Org with Id and Name of each contact.