Skip to main content

Integrating Salesforce with a SOAP web service - Apex callouts



In today' world most APIs and integrations are REST, however sometimes you will encounter a need to integration with SOAP web services. Recently I encountered this in my project where we had to integrate Salesforce with a legacy system that could expose only SOAP web services. There were couple of options for us -

1. Create a rest API service that would play an intermediary role between Salesforce and the soap web service from the external system. Salesforce would consume the rest API to communicate with it.

2. Use a middleware to do the above for us.

3. Integrate Salesforce with the SOAP service directly.

In our situation, we ended up taking option 3. Now, I am not discussing the merits of using a middleware tool here, so lets not get into why we choose option 3. Instead lets focus on learning how simple and easy it is to integrate Salesforce with a SOAP web service.

For our learning experience today, i will use a web service freely available on the internet - http://www.w3schools.com/webservices/tempconvert.asmx
Thanks to W3Schools for this demo service. W3Schools is a great resource for anyone learning different concepts and tools of web programming.

This webservice exposes two operations - CelciusToFahrenheit and FahrenheitToCelcius. As the names state, very obviously, they can be used to convert values from one scale of temperature to another.

In our example, i am going to create a simple Visualforce page with an input textbox for the user to enter a value, a button to invoke the webservice and an output field to show the converted value. All very basic.

Now, in the real world, you can use the concepts I share below to actually do your more sophisticated use cases. The steps to setup and invoke the webservice from Salesforce will remain the same. The mechanism you choose to invoke the webservice in your usecase and show/use its results will be different.

Another important topic, which i hope to blog separately is - patterns around Apex webservice Callouts. Briefly -
1. The webservice callout can be done synchronously. The user as well as system resources will wait for the web service to reply back and for your code to finish processing the response.
This pattern has the disadvantage of being a possible governor limit issue causing pattern. More in the post about these patterns.
2. The webservice callout can be done asynchronously. One way to do it is using future method. While it has advantages, there are limitations too.
3. Another way to do the callout is using the Continuation pattern. This pattern allows the user to see synchronous behavior while system resources are used asynchronously to avoid the governor limits.

I will try and show all three patterns in my blog posts with this example.

In this post, lets setup all the required steps to be able to make our apex webservice callout later.

  • First lets start by downloading the WSDL from the service. In a browser, go to below URL to get the wsdl from W3Schools - 
http://www.w3schools.com/webservices/tempconvert.asmx?wsdl

You can right click in the browser and select view source. Copy the content and save it as a file with name "tempconvert.wsdl"

  • Next we will need to modify this wsdl file. Let me explain why. 
  In Salesforce, typically the next step would be to import the wsdl file to generate the Apex classes and the webservice stub. This is similar to JAVA development where you would import the wsdl to create the resources that will help you invoke the webservice. Now importing a wsdl into Salesforce to generate the Apex stub class has several limitations. Some noteworthy ones are -
    • It does not support attributes
    • It does not support complex types that extend a base type
    • It does not support multiple ports
  If your wsdl has some of these characteristics, the best you can do is to manipulate the wsdl file to remove some of the conflicting elements and import. Once it is imported, you can look at the generated classes and use them appropriately per your use case.
In our wsdl, for example, there are multiple ports defined. 
My use case is to provide a page that will help convert Fahrenheit values to Celcius. For doing that I just need one of the ports of the webservice. So I am going to carefully delete out the ports - TempConvertSoap12 and TempConvertHttpPost and their corresponding wsdl:bindings from the wsdl file.
The bottom of the resulting wsdl will look like - 

  • Now I can import the wsdl. To do this, we can use an IDE or we can do it from the Salesforce UI. I will do it from the UI. Lets navigate to Setup -> Develop -> Apex Classes. Click on the Generate from WSDL button. Click Browse and find the modified wsdl and then click the Parse WSDL button.
  • This will parse the wsdl and show the webservice classes that will be generated. In our case we choose a simple wsdl, so there is only one class. Click Generate Apex Classes and it will show you the classes that got generated. 


    Now you may wonder why it generated two classes after indicating one. The second class which starts with "Async" is what we can use in the Continuation pattern for Apex callouts. It is auto-generated for us. i will explain it more in the post about Continuation.
  • After you click the Done button, you should see the apex classes that got generated. Open up the classes and look through them to understand how you will use the stub that got generated.

  • If you look through the wwwW3schoolsComWebservices class, you will see that there is a method FahrenheitToCelcius that takes a string input (fahrenheit value), calls the webservice and returns a string (Celcius value). This is the stub we want to use for our visualforce page.
  • Before we can test this stub, we need to tell Salesforce that about this web service endpoint. We will add a Remote Site.
  • Navigate to Setup -> Security Controls -> Remote Site Settings. Click New and create a new remote site with the url of the web service endpoint. For example, see below -

  • Now, lets do a quick test of it via the Force IDE. I will just execute an annonymous piece of code to test it.

  • As you can see in the screenshot above, on clicking Execute Annonymous, I can see the result in the User Debug window. The call was successful and got back the value as 0
Thats it, now you have the stub classes required to make your webservice callout. Next you can setup the mechanism to invoke the stub based on your business use case. I will work on the simplistic use case that i took in my next post where I will setup the Visualforce page and built out the synchronous call to the webservice.  More on the asynchronous patterns after that.

Till then enjoy!

Comments

  1. Nowadays, most of the businesses rely on cloud based CRM tool to power their business process. They want to access the business from anywhere and anytime. In such scenarios, salesforce CRM will ensure massive advantage to the business owners.
    Form Builder with Salesforce Integration

    ReplyDelete

Post a Comment

Popular posts from this blog

Workaround to bypass Salesforce SSO

One of the best practices for implementing Single Sign On for your Salesforce org is always ensure there is a way your System administrator can login via the standard login page side-stepping the SSO configuration.  Reason for this is if ever something goes wrong with your Idp provider's service and the SSO authentication responses are not coming as expected, all your users are unable to login. That is, if you have setup your My domain to prevent logins via standard Salesforce login urls (login.salesforce.com). This includes the System administrator as well. Only if your system administrator can somehow login, then he or she can disable the SSO settings for your domain and allow login via the normal login page as a temporary measure. What do you do in such a situation? Well Salesforce has built a workaround for this which is not well documented anywhere (probably for a good reason :) ). I found out about it from a colleague at work. If your my domain url is - https://Com

Salesforce Big Objects - Key learnings

I remember reading about Salesforce Big Objects before they became available and thought maybe it is an option to backup data present in regular objects. That is, instead of taking a backup via an ETL tool or data loader, maybe this will be an option to backup the data in the Force.com platform itself. Now that it is GA and I am reading more about it, i think the use cases for this are more varied. Some use cases I can think of are –  Archival of key data objects within the platform: You may want to use this option if you dont use any other means to backup key data. Also this may be an attractive option for non-large enterprise customers who dont themselves invest on large data warehouses or data lakes in their enterprise architecture. Ex: customer history (if present in tasks and activities) will become huge over years but this is useful information for reporting & customer analysis. Store key information which is large volume in quantity and also high volume in transa

DBAmp for Salesforce - salesforce integration for SQL Server DBAs

Recently i got the opportunity to explore a tool called DBAmp for integration with Salesforce. I found it to be a very useful tool which will help with any data manipulation requirements in Salesforce. Following are my learnings from the exercise. Hope it helps any of you who may need to work with this tool -  DBAmp is a SQL Server package that can be used to integrate with Salesforce. The site where this software is available is - http://www.forceamp.com/ Overview: It essentially installs on top of an existing SQL Server database and provides an OLE DB connector that can be used to connect to Salesforce. Behind the scenes, it executes API calls against Salesforce for any SQL server command it receives. Thus we can create a connection in SQL server to Salesforce org and pull data into tables in the database just as if we are querying against Salesforce tables directly. Use cases for DBAmap + Salesforce: Many use cases exist for using this tool against Salesforce. Pr