Recipes by Category

App Distribution (2) Bundle logic, interface and services for distribution. App Logic (37) The Apex programming language, workflow and formulas for logic. Collaboration (5) The Salesforce Chatter collaboration platform. Database (29) Data persistence, reporting and analytics. Integration (33) Web Service APIs and toolkits for integration. Security (9) Platform, application and data security. Tools (4) Force.com tooling User Interface (36) Visualforce MVC and metadata-drive user interfaces. Web Sites (12) Public web sites and apps with optional user registration and login.
Beta Feedback
Cookbook Home » Setting Up Your Salesforce.com Web Services API Applications

Setting Up Your Salesforce.com Web Services API Applications

Post by Developer Force  (2010-07-16)

Status: Certified
Level: novice

Before working with the API in the recipes in this chapter, perform the following setup steps.

  1. Select a Development Language
  2. Create an Integration User
  3. Select a WSDL
  4. Generate a WSDL Document
  5. If You Use the Partner WSDL
  6. Log In to and Out of the API
  7. Manage Sessions
  8. Change the Session Timeout Value

Select a Development Language

Choose the programming language or languages in which you'll write your application.

If you're interested in building a Web control or client application, write your code in any language that supports Web services, including Java, Perl, Python, PHP, Ruby on Rails, C#.NET, Visual Basic.NET, and Cocoa for Mac OS X. You can find toolkits and code samples for several Web-services-enabled languages on the Developer Force website at wiki.developerforce.com/index.php/API.

Create an Integration User

Client applications that access Salesforce.com through the API must first log in as a Salesforce.com user for authentication. Create a special user in your organization, solely for integration purposes. That way, even if an actual user leaves your organization, you'll always have a user with the correct permissions available.

Assign this user a special profile with the following permissions selected:

  • “API Only”—Specifies that the user can only log in through the API. This prevents the user from being used for any purpose other than integration scenarios.
  • “Modify All Data”—Specifies that the user can view any data stored in the database and edit any field with the editable flag. (Some fields, like CreatedDate, do not have the editable flag set and cannot be edited by any user, regardless of the “Modify All Data” permission.) This permission is also required for any user who wants to upsert non-unique external IDs through the API.
    If you don't need to worry about external IDs, use the “Modify All Records” permission for a more secure integration. This permission further restricts the integration user's access.
In addition, consider restricting the following to enable a more secure integration:
  • All logins use secure access (HTTPS).
  • The integration user's access to just those objects required for the integration.
  • The IP addresses that the integration user can use, perhaps to just the IP address of the server.
  • The organization-wide sharing model—select the lowest level of the hierarchy for the integration user to make changes.
  • All passwords are considered strong and contain at least 20 random characters.

Select a WSDL

A WSDL document is an XML file that describes the format of messages you send and receive from a Web service. It's the protocol that your development environment's SOAP client uses to communicate with external services like Salesforce.com.

Salesforce.com provides two primary WSDL documents for operating on objects and fields in an organization, plus three additional WSDL documents for specific features of workflow rules and the API. Choose the WSDL document you should download and consume based on the type of application you're going to develop:

Enterprise WSDL

The enterprise WSDL is a strongly typed WSDL document for customers who want to build an integration with their Salesforce.com organization only, or for partners who are using tools like Tibco or webMethods to build integrations that require strong typecasting.

Strong typing means that an object in Salesforce.com has an equivalent object in Java, .NET, or whatever environment is accessing the API. This model generally makes it easier to write code because you don't need to deal with any underlying XML structures. It's also safer because data and schema dependencies are resolved at compile time, not at runtime.

The downside of the enterprise WSDL, however, is that it only works with the schema of a single Salesforce.com organization because it's bound to all of the unique objects and fields that exist in that organization's data model. Consequently, if you use the enterprise WSDL, you must download and re-consume it whenever your organization makes a change to its custom objects or fields. Additionally, you can't use it to create solutions that can work for multiple organizations.

Partner WSDL

The partner WSDL is a loosely typed WSDL document for customers, partners, and ISVs who want to build an integration or an AppExchange app that can work across multiple Salesforce.com organizations.

With this WSDL document, the developer is responsible for marshaling data in the correct object representation, which typically involves editing the XML. However, you're also freed from being dependent on any particular data model or Salesforce.com organization. Consequently, if you use the partner WSDL, you only need to download and consume it once, regardless of any changes to custom objects or fields.

Outbound Message WSDL

The Outbound Message WSDL document is for developers who want to send outbound messages from a workflow rule or approval process to an external service.

Apex WSDL

The Apex WSDL document is for developers who want to run or compile Apex scripts in another environment.

Metadata WSDL

The Metadata WSDL document is for users who want to use the Metadata API to retrieve or deploy customization information, such as custom object definitions and page layouts. See “Understanding the Metadata API” in the Force.com Metadata API Developer's Guide.

Delegated Authentication WSDL

The delegated authentication WSDL document is for users who want to created a delegated authentication application to support single-sign on. You can also download a client certificate for validating requests generated by Salesforce.com.

Generate a WSDL Document

If you want to generate a WSDL document other than an Outbound Message WSDL document, log in to your Salesforce.com organization and click Setup | Develop | API. Right-click the WSDL document you want to generate, and select Save Link As in Firefox, or Save Target As in Internet Explorer.

If you want to view a WSDL document without downloading it, simply click the download link for the WSDL document you want to view.

To keep track of the WSDL documents you download, name them with a date/time stamp.

If you want to generate an Outbound Message WSDL document, click Setup | Create | Workflow & Approvals | Outbound Messagaes. Select the name of the outbound message and then click Click for WSDL. This file is bound to the outbound message and contains the instructions about how to reach the endpoint service and what data is sent to it.

If You Use the Partner WSDL

If you want to use the partner WSDL, but you don't know how to work with the loosely typed SOAP messages, use the following information.

The partner WSDL is based on a generic SObject, which represents a Salesforce.com record such as a particular account or contact. Every SObject has the following properties:

Name Type Description
Type string The API name of the object on which this SObject is based. For example, Account and Position__c.
ID ID The unique ID for this SObject. For the create() call, this value is null. For all other API calls, this value must be specified.
Any XMLElement[] (in .NET)

MessageElement[] (in Java)

An array of fields for the SObject. Each element of the array consists of an XML tag, where the name of the field is the name of the element, and the value of the field is the body of the tag. For example:

<name>value</name>

FieldsToNull string[] An array of one or more field names whose value you want to explicitly set to null. This array is used only with the update() or upsert() calls.

Note that you can only specify fields that you can update and that are nillable. For example, specifying an ID field or required field results in a runtime error.

The partner WSDL provides methods that allow you to work with these properties so that you can perform the same tasks with the partner WSDL as you can with the enterprise WSDL. For example, the following Java code creates a job application record using the enterprise WSDL:

public Job_Application__c createJobApp(String candidateId,
String positionId) {
	Job_Application__c jobApp = new Job_Application__c();
	jobApp.setCandidate__c(new ID(candidateId));
	jobApp.setPosition__c(new ID(positionId));
	jobApp.setStatus__c("New");
	SaveResult [] sr = binding.create(new SObject[] {jobApp});
	if(!sr[0].isSuccess())
	throw new SaveException(sr[0]);
	jobApp.setId(sr[0].getId());
	return jobApp;
}

The same createJobApp() method can also be written in Java with the partner WSDL:

public SObject createJobApp(String candidateId,
                            String positionId) {
    SObject jobApp = new SObject();
    // Submit four fields as part of the Any array on the 184
    // Chapter 11:Writing Web Controls and Client Applications
    // Job_Application__c record
    MessageElement[] fields = new MessageElement[3];
    // Candidate id
    field[0] = util.createNewXmlElement("Candidate__c", candidateId);
    // Position id
    field[1] = util.createNewXmlElement("Position__c", positionId);
    // Status
    field[2] = util.createNewXmlElement("Status__c", "New");
    jobApp.set_any(fields);
    jobApp.setType("Job_Application__c");
    SaveResult [] sr = binding.update(new SObject[] {jobApp});
    if(!sr[0].isSuccess())
        throw new SaveException(sr[0]);
    jobApp.setId(sr[0].getId());
    return jobApp;
}

The following VB.NET code creates a position record using the enterprise WSDL:

Dim p as New Position__c
p.Id = "a00D0000005iYiq"
p.Name = "Analyst"
p.Status__c = "Open"
binding.create(New sObject() {p})

This code can be written using the partner WSDL as follows:

Dim p as New SObject
  p.Type = "Position__c" 
  p.Id = "a00D0000005iYiq"
  Dim doc as New XmlDocument
  Dim e1, e2 as XmlElement
  e1 = doc.CreateNewElement("Name")
  e2 = doc.CreateNewElement("Status")
  e1.InnerText = "Analyst"
  e2.InnerText = "Open"
  p.Any = new XmlElement() {e1,e2}
  binding.update(New sObject() {p})
In these examples, notice that Java and .NET use different elements to represent field name/value pairs. For example, given the following name/value pair: <City__c>Chicago</City__c>
  • Java uses a MessageElement where:
    • City__c is the Name
    • Chicago is the Value
  • .NET uses an XMLElement where:
    • City__c is the LocalName
    • Chicago is the InnerText

Use the partner WSDL in conjunction with the describeGlobal() and describeSObjects()API calls to get object metadata. For example, a particular object's type is defined in the name field in the returned DescribeSObjectResult. Likewise, the name of an object's field is defined in the name field of the Field type in the returned DescribeSObjectResult.

Log In to and Out of the API

If a client application originates from outside the Salesforce.com user interface, it must first log in to the API. The best practice is to log out of the API when the client application completes its work. Use the following information to understand how to log in and log out from a client application.

Similar to the way the login page works in the Salesforce.com user interface, the login() call takes a username and password and executes a login sequence on https://login.salesforce.com/. If the login is successful, the login() call returns a session ID and URL. The session ID represents the user's authentication token and the URL points to the host that contains data for the user's organization.

For performance and reliability, the platform runs on multiple instances (for example, na1.salesforce.com and na2.salesforce.com), but data for any single organization is always consolidated on a single instance. As long as you use the URL that is returned from the login() call, you should never need to know the actual instance that hosts an organization's data.
Authenticating with the login() Call

Once you've obtained a session ID and server URL, you'll generally include the session ID in every API call, and you'll direct your client to make the API request to the host that you obtained.

It's not necessary to use login() when writing an s-control that executes within the Salesforce.com user interface because the user accessing the s-control has already logged in and acquired a session ID.

To log in, acquire a Salesforce.com session ID and the appropriate host for your organization by using the login() call.

For example, the following Java code from the wrapper class described in Using a Wrapper Class for Common API Functions:
  • Logs in to Salesforce.com
  • Sets the login time
  • Resets the URL for the SOAP binding stub to the returned server URL
  • Creates a new session header for the binding class variable
  • Updates the wrapper class' sessionID and serverURL variables
/**
* This method is used to log in to salesforce and set the
* private class variables for the wrapper, including the
* session ID.
*/  

public void login() throws UnexpectedErrorFault, InvalidIdFault,
						   LoginFault, RemoteException, 
						   ServiceException {

	resetBindingStub();
	LoginResult loginResult = binding.login(username, password);
	this.nextLoginTime = System.currentTimeMillis() + 
						 (this.sessionlength * 60000);

	this.binding._setProperty(SoapBindingStub.
							  ENDPOINT_ADDRESS_PROPERTY,
							  loginResult.getServerUrl());
	this.sessionId = loginResult.getSessionId();
	this.serverUrl = loginResult.getServerUrl();

	// Create a new session header object and set the
	// session id to that returned by the login
	SessionHeader sh = new SessionHeader();
	sh.setSessionId(loginResult.getSessionId());
	this.binding.setHeader(new 
	 SforceServiceLocator().getServiceName().getNamespaceURI(),
	   "SessionHeader", sh);
}

This VB .NET code performs the same logic as for the VB.NET version of the wrapper class (see Using a Wrapper Class for Common API Functions):

public Job_Application__c createJobApp(String candidateId,
Public Sub Login()
	Dim lr As sforce.LoginResult
	Me._binding.Url = Me._host
	lr = Me._binding.login(username, password)
	Me._nextLoginTime = Now().AddMinutes(Me.sessionlength)
	'Reset the SOAP endpoint to the returned server URL    

	Me._binding.Url = lr.serverUrl
	Me._binding.SessionHeaderValue = New sforce.SessionHeader
	Me._binding.SessionHeaderValue.sessionId = lr.sessionId
	Me._sessionId = lr.sessionId
	Me._serverURL = lr.serverUrl
End Sub

To log out of the session you created, issue the logout() call.

Java:

/**
* This method is used to log out of salesforce
*/  

public void logout() {
   try {
       binding.logout();
   }
   catch (Exception e) {
       System.out.println("Unexpected error:\n\n" + e.getMessage());
   }
}

VB.NET:

Public Sub Logout()
	Me._binding.logout()
End Sub

Manage Sessions

An integration may last longer than the session timeout value specified for an organization, but logging in to Salesforce.com every time you need to make an API call is inefficient. To manage sessions, use the information in this section.

The session timeout value is the amount of time a single session ID remains valid before expiring. Sessions expire automatically after a predetermined length of inactivity, which can be configured in Salesforce.com by clicking Setup | Security Controls. The default is 120 minutes (two hours). If you make an API call, the inactivity timer is reset to zero.

You can manage sessions by writing a method that checks to see whether your session ID is about to expire by comparing your last login time with the current session length. When this method returns true, log in again.

For example, the following Java code from the wrapper class discussed in Using a Wrapper Class for Common API Functions implements a loginRequired() method:

/**
* This method returns true if a login to Salesforce is
* necessary, otherwise false. It should be used to check the
* session length before performing any API calls.
*/  

private boolean loginRequired() {
	if (sessionId == null || sessionId.length() == 0) 
		return true;
	return !isConnected();
}

/**
* This method checks whether the session is active or not
* @return boolean
*/  

public boolean isConnected() {
	return System.currentTimeMillis() < nextLoginTime;
}

This VB.NET function implements the same logic:

Private Function loginRequired() As Boolean
        loginRequired = Not (isConnected())
    End Function

    Public Function isConnected() As Boolean
        If _sessionId <> "" And _sessionId <> Nothing Then
            If Now() > Me._nextLoginTime Then
                isConnected = False
            End If
            isConnected = True
        Else
            isConnected = False
        End If
    End Function
	
Be sure that the value you use for session length is no more than the configured session timeout value. Because the session timeout value for an organization is not accessible through the API, it's a good idea to build applications that assume a thirty-minute session timeout so that administrators don't inadvertently break your integrations.

This example is very simple. Another, more robust option is to catch the session expiration remove exception (Exception Code - INVALID_SESSION_ID) and only then log in again.

Share

Recipe Activity - Please Log in to write a comment

Is the "API Only" profile checkbox still available? With the new Profile interface, I'm unable to locate it. There is an "API Enabled" checkbox, but I don't think it performs the same function.

by JPClark3  (2013-07-24)

Here are some pointers and sample code on using the WSDL APIs with JAXB that is part of Java 6 so no extra jars are required:

  • http://force201.wordpress.com/2011/02/06/quick-summary-of-how-to-get-started-with-the-enterprise-wsdl-api-via-javas-jaxb/
  • http://force201.wordpress.com/2011/02/16/quick-summary-of-how-to-get-started-with-the-metadata-wsdl-api-via-java%E2%80%99s-jaxb/

by Keith Clarke  (2011-02-16)

These code samples are the same ? 

they all show the code for  createJobApp()

but the comments refer to different methods

by ronhess.0  (2010-11-10)

X

Vote to Verify a Recipe

Verifying a recipe is a way to give feedback to others and broaden your own understanding of the capabilities on Force.com. When you verify a recipe, please make sure the code runs, and the functionality solves the articulated problem as expected.

Please make sure:
  • All the necessary pieces are mentioned
  • You have tested the recipe in practice
  • Have sent any suggestions for improvements to the author

Please Log in to verify a recipe

You have voted to verify this recipe.