visit
<soapenv:Envelope xmlns:soapenv="//schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:enterprise.soap.sforce.com">
<soapenv:Header>
<urn:LoginScopeHeader>
<urn:organizationId>12345</urn:organizationId>
<urn:portalId>abcde</urn:portalId>
</urn:LoginScopeHeader>
</soapenv:Header>
<soapenv:Body>
<urn:login>
<urn:username>johndoe</urn:username>
<urn:password>mypassword</urn:password>
</urn:login>
</soapenv:Body>
</soapenv:Envelope>
SOAP is mostly used to create an API or web service to exchange server-to-server information. Therefore, it is very important for the two systems to establish trust. Salesforce provides multiple ways to accomplish authentication.
First, you need a Salesforce org. Salesforce provides free Developer edition orgs, and signing up for one is straightforward. Go to the sign-up page and provide your details. You should receive an invite link within a few minutes.
To create a SOAP web service in Salesforce, we will need to create a globally defined Apex custom class. In our class, we’ll use the webservice
keyword and static
definition modifier for every method we want to expose. Adding the webservice
keyword automatically gives global access to the method it is added to.
In order to create this class in our shiny, new org, we go to Setup, and then find Custom Code -> Apex Classes. In the table listing existing classes, we click New.
Below, we have a sample ContactAPI
class that exposes a createContact
method used to create new Contact records in Salesforce. The method accepts a Contact’s details as parameters and inserts a new Contact record.
global class ContactAPI {
webservice static String createContact (String firstName, String lastName, String contactEmail, String salutation) {
try {
Contact newContact = new Contact();
newContact.Salutation = salutation;
newContact.FirstName = firstName;
newContact.LastName = lastName;
newContact.Email = contactEmail;
insert newContact;
return 'Successfully inserted new Contact! Id:' + String.valueOf(newContact.Id);
} catch (Exception e) {
return 'Error:' + e.getMessage();
}
}
}
Next, we click Save.
We now need to generate a WSDL file and provide it to the external application or third-party developers who can then consume it to call our createContact
method.
After creating our ContactAPI
class, we see it show up in the list of Apex classes. In the row for ContactAPI, we click on the WSDL link to generate a WSDL.
We save this file to our local machine, naming it contactAPI-wsdl.xml
.
To generate the Enterprise WSDL for our Salesforce org, we go to the Setup page, and then find Integrations -> API. Then, we click on Generate Enterprise WSDL.
We save this file to our local machine, naming it enterprise_wsdl.xml
.
For the purpose of this demo, we’ll use , which is an open-source tool to test SOAP (and other protocols) web services. With SoapUI installed and running, we create a new SOAP Project, providing a name and selecting our enterprise_wsdl.xml
file as the initial WSDL.
First, we need to authenticate our web application to Salesforce. We do this by using the login
call and providing our login credentials.
For added security, we also need to add a Security Token to our password to authenticate. We can get a security token by going to the Settings page and selecting Reset My Security Token on the left. Then, press the button with the same name. We will then receive our security token by email.
With our token in hand, we select the login
SoapBinding in SoapUI. Ensure you have the correct URL depending on your org. If you just signed up for a developer account, the URL should be . If you are testing this in a Sandbox, then the URL should be . Ideally, the generated Enterprise WSDL will already have the correct URL.
We press the green Play button on the top left of the window to send the request. We receive a response that looks like this:
The critical pieces that we are looking for in the response are sessionId
and serverUrl
. In order to call our web service, we need to provide the sessionId
together with other parameters in our call. We copy down this sessionId
, as we will need this later.
Let’s call our ContactAPI
class and create a Contact in Salesforce. To do this, we need to add our ContactAPI WSDL file, contactAPI-wsdl.xml
, to our project. We right-click on the project folder and select Add WSDL.
After adding the WSDL, it also appears in the left menu like below. Double-click on Request 1 to see the request. For this example, we can remove everything from the SOAP envelope header except for the SessionHeader
with sessionId
node.
After removing the unwanted nodes, we provide the sessionId
that we copied from our login call earlier. Then, in the Body
section of the envelope, we provide the details of the contact to be created.
We press the green Play button on the top left. Vóila! We have successfully created a Contact in Salesforce and received its Id
.
Let’s look inside our Salesforce org to see if everything was created correctly. We go to our Salesforce org, click the App Launcher waffle icon on the left and then type Contact
in the search bar to find and select Contacts.
By default, we land on the Contacts page with the Recently Viewed Contacts list view. Click the down arrow and select either All Contacts or My Contacts list view.
Note: If you are in a Developer org, you will see a bunch of dummy Contacts (and other records) that Salesforce creates for you to test the platform.
Lastly, in order to ensure that our API is working properly, let’s send a bad request to see what we get as a response. We’ll simply send another request to our SOAP web service, but this time replace the .
in the email address with a ,
instead.
This time, we receive an error message (as we programmed in the API).
Error:Insert failed. First exception on row 0; first error: INVALID_EMAIL_ADDRESS, Email: invalid email address: sheila@gmail,com: [Email]
@isTest
private class TestContactWebService {
static testMethod void testInsertNewContact() {
// Create test data for positive test
String salutation = 'Mr.';
String firstName = 'Max';
String lastName = 'Bond';
String emailAddress = '[email protected]';
Test.startTest();
//Call the method with parameters
String result = ContactAPI.createContact(firstName, lastName, emailAddress, salutation);
Test.stopTest();
Contact newContact = [SELECT FirstName FROM Contact WHERE LastName = 'Bond'];
System.assertEquals(newContact.FirstName, 'Max', 'Assert Error: Please check the ContactAPI class');
}
static testMethod void testInsertNewContactFail() {
// Create test data for failing test
String salutation = 'Mr.';
String firstName = 'Max';
String lastName = 'Bond';
// The email address has , instead of .
String badEmailAddress = 'm.bond@mi5,gov,uk';
Test.startTest();
//Call the method with parameters
String result = ContactAPI.createContact(firstName, lastName, badEmailAddress, salutation);
Test.stopTest();
// This should contain the Error substring that we added to the catch block above.
System.assert(result.contains('Error:'), 'Fail Assert Error: Please check the ContactAPI class');
}
}