Sunteți pe pagina 1din 12

SFDC Integration:

SFDC Integration

What is SOAP Integration ?

Simple Object Access Protocol (SOAP) is a standard protocol specification for message exchange
based on XML. Communication between the web service and client happens using XML messages.
SOAP defines the rules for communication like what are all the tags that should be used in XML and
their meaning.

What is REST?

RESTful web service uses architectures that use HTTP or similar protocolsby restricting the interface
to use standard operations like GET, POST, PUT, DELETE for HTTP.

Salesforce.com’s unique multitenant architecture—in which all users and applications share a single,
common infrastructure and code base that is centrally maintained—is the key to creating
integrations that don’t break. The Force.com multitenant platform, the Force.com Web Services API,
and a wide network of integration partners come together to provide Rapid time to value,Simplicity,
Flexibility and choice and proven success and predictability as benefits.

Salesforce robust integration capabilities give a free hand to the Administrators/Developers to build
the integration in mainly two ways that are SOAP and REST APIs.

When to use SOAP API ?

Use SOAP API to create, retrieve, update or delete records, such as accounts, leads, and custom
objects. With more than 20 different calls, SOAP API also allows you to maintain passwords, perform
searches, and much more. Use SOAP API in any language that supports Web services.

When to Use REST API ?

REST API provides a powerful, convenient, and simple REST-based Web services interface for
interacting with Salesforce. Its advantages include ease of integration and development, and it’s an
excellent choice of technology for use with mobile applications and Web projects. However, if you
have a large number of records to process, you may wish to use Bulk API, which is based on REST
principles and optimized for large sets of data.

CALL INS
Call Ins
I. Ext system to Salesforce Integration using SOAP API.

Capital Info Solutions


# 86 86 86 42 86
SFDC Integration:

System defined WSDLs:

Enterprise WSDLs: It is strongly typed and It provides informationabout your schema, data types,
and fields to your development environment, allowing for a tighter integration between itand the
Force.com Web service.

Note the following when generating the enterprise WSDL:

1. If new custom fields or objects are added to, renamed, or removed from your organization’s
information, you need to regenerate the WSDL file in order to access them.
2. The generated WSDL contains the objects and fields in your organization, including those
available in the selected versions of each installed package. If a field or object is added in a
later package version, you must generate the enterprise WSDL with that package version to
work with the object or field in your API integration.

Partner WSDLs:

This API is for salesforce.com partners who are developing client applications for multiple
organizations. As a loosely-typed representation of the Salesforce object model, the partner WSDL
can be used to access data within any organization.

User defined WSDLs:

Enterprise WSDL or Partner WSDL is used to perform basic Create, Read, and Update or Delete
operations on sObjects. If requirement is more complex than mere Query or update an object
record, Salesforce has given a facility to the Developers to generate their own Buiseness logics and
expose them as Web Services.

Any method in Apex class can be exposed as Web Service if the method is prefixed with ‘Web
Service’ keyword.

Please consider following points while defining custom web services,

1. You cannot use the web Service keyword when defining a class. However, you can use it to
define top-level, outer class methods, and methods of an inner class.
2. You cannot use the web Service keyword to define an interface, or to define an interface's
methods and variables.
3. You cannot use the web Service keyword in a trigger because you cannot define a method in
a trigger.
4. All classes that contain methods defined with the web Service keyword must be declared as
global. If a method or inner class is declared as global, the outer, top-level class must also be
defined as global.
5. Methods defined with the web Service keyword are inherently global. These methods can be
used by any Apex code that has access to the class. You can consider the web Service
keyword as a type of access modifier that enables more access than global.
6. You must define any method that uses the web Service keyword as static.

Capital Info Solutions


# 86 86 86 42 86
SFDC Integration:

Sample Example for user defined WSDL:

global class SpecialAccounts {

global class AccountInfo {


webService String AcctName;
webService Integer AcctNumber;
}

webService static Account createAccount(AccountInfo info) {


Account acct = new Account();
acct.Name = info.AcctName;
acct.AccountNumber = String.valueOf(info.AcctNumber);
insert acct;
return acct;
}

webService static Id [] createAccounts(Account parent,


Account child, Account grandChild) {

insert parent;
child.parentId = parent.Id;
insert child;
grandChild.parentId = child.Id;
insert grandChild;

Id [] results = new Id[3];


results[0] = parent.Id;
results[1] = child.Id;
results[2] = grandChild.Id;
return results;
}
}

Tips or Suggestions for CALL IN SOAP Integration:

1. Any web services that are given by SFDC developer to External system’s developers should
be provided along with Sample Request and Response.
For standard/system defined wsdls please find the below link where SFDC provides all
sample requests and responses.
http://wiki.developerforce.com/page/Sample_SOAP_Messages_%2810.0_API%29.

Capital Info Solutions


# 86 86 86 42 86
SFDC Integration:

2. Since user defined WSDLs are generated for very specific requirement , it is our duty to
generate sample requests/responses, to do so , just consume the wsdl into SOAP UI tool and
check how a sample request looks like and what inputs are required for the User defined
wsdl. Since we already know from what Apex class this web service is generated we should
be in a position to recognize the required inputs. Once the inputs are given perform run
operation which gives you sample response for the sample request. Copy both request and
response and enclose both with Web service that is generated by Apex class then share
them to the external person.

II. Ext system to Sales force Integration using REST API


As how any apex class can be exposed as webservices with ‘WebService’ key word in a
similar way we can also expose any class as Rest service using ‘@RestResource’.

Sample code for Rest Integration in CALL In is below,


@RestResource(urlMapping='/Account/*')
global with sharing class MyRestResource {

@HttpDelete
global static void doDelete() {
RestRequestreq = RestContext.request;
RestResponse res = RestContext.response;
String accountId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);
Account account = [SELECT Id FROM Account WHERE Id = :accountId];
delete account;
}

@HttpGet
global static Account doGet() {
RestRequestreq = RestContext.request;
RestResponse res = RestContext.response;
String accountId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);
Account result = [SELECT Id, Name, Phone, Website FROM Account WHERE Id =
:accountId];
return result;
}

@HttpPost
global static String doPost(String name,
String phone, String website) {
system.debug('here is the name '+name);
Account account = new Account();
account.Name = name;
account.phone = phone;
account.website = website;
insert account;
return account.Id;
}
}
Capital Info Solutions
# 86 86 86 42 86
SFDC Integration:

Tips or Considerations in REST Integration.

1. Use apigee.com or Workbench.developerforce.com while checking the REST resources.

2. While writing code for rest integration all read operations should be written in a method
which is exposed/prefixed with @HttpGet for better security and write operations should be
exposed as @HttpPost annotation.

CALL OUTS

III. Calling External system from SFDC using SOAP Integration


1. Convert the WSDL to apex class (Set up Develop - > Apex Class -> Generate from WSDL)
Understand the generated apex class - Which one is responsible for login method, request
class, response class and the original calling method.
2. Apex class/trigger to execute your logic- On button click I want to call the external web
service. Hence,
3. Create a custom button and open a VF page on click of this custom button, this VF page will
be associated to the apex class
4. Add the remote site setting for the end point URL given

After a class is generated from WSDL, just pay attention to on required methods, need not to
understand the entire code. Every name space in the WSDL will be converted as a class, every
element in WSDL will be converted as a property and each operation in WSDL is going to be a
method in Apex class.

To understand in a better way it is advisable to first check in SOAP UI and perform intended
operations then consume in SFDC.

Once the class is generated try to see whether class contains any login methods (here we are going
to use open source WSDL which has no login method). If so create a instance to the class in which
login method is present and call the method on that instance.

After login response says successful connection, perform the intended operations by calling the
methods on already created instance.

Here is the example to get the EU 2012 details which is exposed as Web services.

Link to WSDL is here :http://footballpool.dataaccess.eu/data/info.wso?WSDL

Consume the WSDL as mentioned above it generates the required classes.

Capital Info Solutions


# 86 86 86 42 86
SFDC Integration:

To call the above class write another class as below, sample code is below..

public with sharing class controller_Invoke_footBall {

public String[] goalKeepers { get; set; }

public booleanisYellowCards {get;set;}


Public Integer noOfCards {get;set;}
Public string country {get;set;}
Public footballpoolDataaccessEu.tTeamInfo[] eachTeamInfo {get;set;}
//Public footballpoolDataaccessEu.tFullTeamInfoteamMembersList {get;set;}

//public footballpoolDataaccessEu.ArrayOfString defenders {get;set;}

public string [] defendersList {get;set;}


public string [] teamForwardsList {get;set;}
public string [] teamGoalKeepersList {get;set;}
public string [] teamMidfieldsList {get;set;}
//public String [] goalKeepers;

public controller_Invoke_footBall () {

getGroupCompInfo('B');
}

public void eu2012 () {

footballpoolDataaccessEu.InfoSoap ret = new footballpoolDataaccessEu.InfoSoap ();


noOfCards = ret.GroupCount();
system.debug('Total Groups >> '+noOfCards );

footballpoolDataaccessEu.ArrayOfStringallGoalKeepers = new
footballpoolDataaccessEu.ArrayOfString ();
allGoalKeepers = ret.AllGoalKeepers(country);
goalKeepers = allGoalKeepers.string_x;

// system.debug('Total Goal Keepers >> '+goalKeepers);


getOverallTeamInfo(country);

public void getGroupCompInfo (String poul) {


footballpoolDataaccessEu.InfoSoap ret = new footballpoolDataaccessEu.InfoSoap ();
footballpoolDataaccessEu.ArrayOftTeamInfocompList = ret.GroupCompetitors(poul);

Capital Info Solutions


# 86 86 86 42 86
SFDC Integration:

eachTeamInfo = compList.tTeamInfo;

system.debug('here is the Group A\'s Teams $$$'+eachTeamInfo);


}

public void getOverallTeamInfo (String country) {


footballpoolDataaccessEu.InfoSoap ret = new footballpoolDataaccessEu.InfoSoap ();
footballpoolDataaccessEu.InfoSoapTeamInfoRes = new footballpoolDataaccessEu.InfoSoap ();
footballpoolDataaccessEu.tFullTeamInfoteamMembersList = ret.FullTeamInfo(country);

footballpoolDataaccessEu.ArrayOfString defenders = teamMembersList.sDefenders;


footballpoolDataaccessEu.ArrayOfStringteamForwards = teamMembersList.sForwards;
footballpoolDataaccessEu.ArrayOfStringteamGoalKeepers = teamMembersList.sGoalKeepers;
footballpoolDataaccessEu.ArrayOfStringteamMidfields = teamMembersList.sMidFields;

defendersList = defenders.string_x;
teamForwardsList = teamForwards.string_x;
teamGoalKeepersList = teamGoalKeepers.string_x;
teamMidfieldsList = teamMidfields.string_x;

system.debug('here is the Team Greece\'s defenders list $$$'+teamMembersList.sDefenders);

IV. Calling external system from SFDC using REST API

Sample code for REST API with JSON parsing.

public with sharing class controller_restApi_geoIp {

public String ipAddress{get;set;}


public string location {get;set;}
public string ret {get;set;}
public string resString {get;set;}
public booleanrenderField {set;get;}
Public List<String>fieldName {get;set;}
Public List<String>fieldValue;

public void save (){


fieldName = new list<String> ();
httpRequestreq = new httprequest ();
req.setendpoint('http://freegeoip.net/json/'+ipAddress);
req.setmethod('GET');
system.debug('http://freegeoip.net/json/'+ipAddress);
http ht = new http ();

Capital Info Solutions


# 86 86 86 42 86
SFDC Integration:

httpresponse res = ht.send(req);


resString = res.getbody();
system.debug(res.getbody());
JSONParser parser = JSON.createparser(res.getbody());

while(parser.nextToken() != null){
if(parser.getCurrentToken() == JSONToken.FIELD_NAME){

//parser.nextToken();
ret = parser.getText();
parser.nextToken();
ret = ret+':: '+ parser.getText();

fieldName.add(ret);
//parser.nextValue();
system.debug('here is the fieldname ^^^^^^^****^^^^^^ '+ret);
}

// String str = parser.getText();


// ValueDict.add('a'); VALUE_STRING
}
}
}

General Considerations in integrations:

1. In real time scenarios authentication of external system (login credentials) need to be


provide in Apex classes while Call outs irrespective of REST or SOAP. Since Dev/Test/Prod
sandboxes should connect their respective external system counterparts we cannot
hardcode the credentials in apex classes due to the fact that once Test code has been moved
to PROD we cannot modify the Apex class to change credentials from Test to Prod. In order
to accomplish this use Custom settings or Custom labels to save the credentials of the
External system in each sandbox accordingly and keep call the custom settings/Labels all the
time from Apex class.
Ensure that Prod sandbox will have its’ external system Credentials to be saved in Custom
settings, same case with Dev and Test.

Inbound Email example:

global class SampleCreateContactEmailExample implements Messaging.InboundEmailHandler{


global
Capital Info Solutions
# 86 86 86 42 86
SFDC Integration:

Messaging.InboundEmailResulthandleInboundEmail(Messaging.inboundEmailemail,Messaging.Inbou
ndEnvelopeenv){

Messaging.InboundEmailResult result = new Messaging.InboundEmailResult();


Contact contObj = new Contact();
try {
contObj = [select id, email, Subject__c, Email_Body__c, lastname from contact where email
=:email.fromAddress limit 1];
} catch(Exception e)
{
System.debug('************'+e.getMessage());
}
if(contObj.Id != null){
contObj.Subject__c = email.subject;
contObj.Email_Body__c = email.plainTextBody;
}
else{
contObj.lastname = email.fromName;
contObj.email = email.fromAddress;
contObj.Subject__c = email.subject;
contObj.Email_Body__c = email.plainTextBody;
}
upsertcontObj;
// Insert attachments
List<Attachment>lstAtt = new List<Attachment>();
if( email.textAttachments != null ){
for (Messaging.Inboundemail.TextAttachmenttxtAttachment : email.textAttachments) {
Attachment attachment = new Attachment();
attachment.Name = txtAttachment.fileName;
attachment.Body = Blob.valueOf(txtAttachment.body);

attachment.ParentId = contObj.Id;
lstAtt.add(attachment);
}
}
if( email.binaryAttachments != null){
for (Messaging.Inboundemail.BinaryAttachmentbinaryAttachment : email.binaryAttachments)
{
Attachment attachment = new Attachment();
attachment.Name = binaryAttachment.fileName;
attachment.Body = binaryAttachment.body;
attachment.ParentId = contObj.Id;
lstAtt.add(attachment);
}
}
if(lstAtt.size() > 0)
insert lstAtt;
result.success = true;
return result;
}
}

Capital Info Solutions


# 86 86 86 42 86
SFDC Integration:

Outbound Email:

Using Messaging interface, we can configure the system to send an emails to the customers/users or
whomsoever need to be notified.

Below is the sample code for Outbound email along with attachment insertion, call this in a trigger
or controller as per your requirement.

To set the FromAddress to emails,we need to set up Organizational email address.

To do that please select Setup > Email Administration > Organization-Wide Email Addresses and
create new email address. We can query the Org wide email address in apex code as below..

Messaging.reserveSingleEmailCapacity(2);
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

String[] toAddresses = new String[] {'pavan.kalapatapu@ge.com'};


String[] ccAddresses = new String[] {'pavan.kalapatapu@ge.com'};

// Assign the addresses for the To and CC lists to the mail object.
mail.setToAddresses(toAddresses);
mail.setCcAddresses(ccAddresses);

mail.setReplyTo('pavan.kalapatapu@ge.com');

mail.setSenderDisplayName('Salesforce Support');
mail.setSubject('New Mail is Created : ');
mail.setBccSender(false);

mail.setUseSignature(false);
mail.setPlainTextBody('thanks for using our SFDC OutBound Email Message');

mail.setHtmlBody('thanks for using our SFDC OutBound Email Message');

Messaging.EmailFileAttachmentefa = new Messaging.EmailFileAttachment();


Blob emailbody = blob.topdf('here is the atta body');
efa.setFileName('attachment.pdf');
efa.setBody(emailbody);
mail.setFileAttachments(new Messaging.EmailFileAttachment[] {efa});

Capital Info Solutions


# 86 86 86 42 86
SFDC Integration:

// Send the email you have created.


Messaging.SendEmailResult[] mailResult = Messaging.sendEmail(new
Messaging.SingleEmailMessage[] { mail });
system.debug('here is the response >> '+mailResult);

XML Parsing:

So often in SOAP and REST integrations we come across XML reading/writing. Salesforce has
provided standard class, called as, DOM which is useful in parsing the XML responses.

Here is the sample example to illustrate how to use methods of DOM class’ methods and properties
in parsing XML data.

// Sample code to parse XML response

public class DomDocument {

// Pass in the URL for the request


// For the purposes of this sample,assume
that the URL
// returns the XML shown above in the
response body
public void parseResponseDom(String url){ Let the sample XML response be like below,
Http h = new Http();
HttpRequestreq = new HttpRequest();
// url that returns the XML in the response <address><name>CapitalInfosolutions</name>
body <street1>Mythrivanam</street1>
req.setEndpoint(url); <street2>Ameerpet</street2>
req.setMethod('GET'); <city>Hyderabad</city>
HttpResponse res = h.send(req); <state>AP</state>
Dom.Document doc = res.getBodyDocument(); <country>India</country>
</address>
//Retrieve the root element for this
document.
Dom.XMLNode address = doc.getRootElement();

String name =
address.getChildElement('name', null).getText();
String state =
address.getChildElement('state', null).getText();
// print out specific elements

Capital Info Solutions


# 86 86 86 42 86
SFDC Integration:

System.debug('Name: ' + name);


System.debug('State: ' + state);

// Alternatively, loop through the child


elements.
// This prints out all the elements of the
address
for(Dom.XMLNode child :
address.getChildElements()) {
System.debug(child.getText());
}
}
}

< End of the Document >

Capital Info Solutions,

Hyderabad.

Capital Info Solutions


# 86 86 86 42 86

S-ar putea să vă placă și