Salesforce: Consuming SOAP Web Service
Importing the WSDL
Salesforce acts as the client calling an external SOAP web service. This process is achieved through Apex callouts using the WSDL (Web Services Description Language) provided by the external system.
- Obtain the WSDL file from the external SOAP service provider.
- In Salesforce Setup, navigate to Apex Classes → Generate from WSDL.
- Upload the WSDL file. Salesforce will then generate Apex classes (referred to as stubs) that represent the SOAP operations and data types defined in the WSDL.
Example Apex Code to Call External SOAP Service
Once the WSDL is imported and the Apex classes are generated, you can write Apex code to interact with the external SOAP service.
For instance, if the external SOAP service offers an operation like getWeather(city), Salesforce will create a stub class based on the WSDL, such as WeatherService.
public class WeatherConsumer {
public static String getWeatherForCity(String cityName) {
// Create an instance of the stub from the generated WSDL class
WeatherServiceSoap ws = new WeatherServiceSoap();
// Set the endpoint (can be from WSDL or overridden if necessary)
ws.endpoint_x = 'https://api.example.com/soap/weather';
// Call the SOAP operation
String result = ws.getWeather(cityName);
System.debug('Weather result: ' + result);
return result;
}
}
Authentication
Many SOAP services require authentication using credentials such as username/password, API key, or token. Salesforce-generated stubs typically include a SoapHeader class where you can set these credentials.
WeatherServiceSoap ws = new WeatherServiceSoap();
ws.inputHttpHeaders_x = new Map<String, String>();
ws.inputHttpHeaders_x.put('Authorization', 'Bearer YOUR_TOKEN');
// Or, if the WSDL defines a LoginHeader, you set it like:
WeatherService.LoginHeader header = new WeatherService.LoginHeader();
header.username = 'myUser';
header.password = 'myPass';
ws.SessionHeader = header;
Testing with Mock Data
When testing Salesforce code that interacts with external SOAP services, it is essential to use mock data to simulate responses. This is due to the restriction on making actual callouts during tests.
@isTest
private class WeatherConsumerTest {
@isTest static void testGetWeatherForCity() {
// Mock the SOAP response
Test.startTest();
// You can use HttpCalloutMock if the SOAP stub internally uses Http
Test.setMock(HttpCalloutMock.class, new WeatherMock());
String result = WeatherConsumer.getWeatherForCity('Cochin');
Test.stopTest();
System.assertEquals('Sunny', result);
}
}
// Mock class
global class WeatherMock implements HttpCalloutMock {
global HttpResponse respond(HttpRequest req) {
HttpResponse res = new HttpResponse();
res.setStatusCode(200);
// Simplified SOAP response body
res.setBody('Sunny');
return res;
}
}
Explanation
- WSDL Import: This step generates Apex classes (stubs) that represent the SOAP service based on the WSDL.
- Stub Usage: Instantiating the stub allows you to call its methods like regular Apex methods.
- Authentication: Authentication is often managed through SOAP or HTTP headers.
- Testing: Utilize HttpCalloutMock to mimic SOAP responses in test classes, as real callouts are restricted.
Key Takeaways
- Salesforce can consume external SOAP services by importing WSDLs and utilizing generated Apex stubs.
- Authentication mechanisms are typically required and can be managed via headers.
- Always incorporate mock-based test classes for SOAP callouts to ensure proper functionality.
- This approach is commonly used to integrate Salesforce with legacy systems that expose SOAP APIs.
