Episode 9 – Integrating with Salesforce (Part 2)

Apex, Apex Hours for Students

Salesforce is a service first platform and external services also require to call Salesforce to retrieve or modify data within Salesforce. Join us as you embark on this wonderful journey to become a champion Salesforce developer.

Episode 9 will be presented by Jayesh Tejwani on Feb 20, 2020 at 6 PM Indian Standard Time.

Agenda

  • External Service Callins to Salesforce
  • Salesforce Vs Apex REST
  • SOAP Callins using WebMethods
  • Enterprise & Partner WSDL
  • Q & A

Most importantly don’t break a leg if you are overwhelmed with the pace of the live sessions. All Apex Hours for Student sessions will be recorded and will be available on our YouTube channel. Please Subscribe our YouTube Channel.


Please register here and follow our ApexHours website to get more notification.

Here is keynote of session

External Service calling to Salesforce

  • Standard REST API
  • Custom REST API

HTTP Request & Response

HTTP Request & Response

Anatomy of a REST API CALL

Standard REST API

Insert a Record 

§Method :- Post
URL:- /services/data/v47.0/sobjects/Case/
Request Body :-

{

“Status” : “New”,

“Origin” : “Phone”,

“Subject” : “Issue with Access”,

“Description” : “Unable to Access”

}

Response

{ “id” : “5003i000004QuGdAAK“, “success” : true, “errors” : [ ] }

DEMO

Salesforce API Explorerhttps://developer.salesforce.com/docs/api-explorer/sobject/Case

•Insert a Record •Find a Record •Find a Record

Workbenchhttps://workbench.developerforce.com/login.php

•Insert •Query •Describe •Describe

Create Custom API

@RestResource(urlMapping=’/Opportunities/*’)
global with sharing class OpportunityManager {
    @HttpPost
    global static ID createOpportunity(String name, String stage, String closedate, String source) {
        Opportunity newOpportunity = new Opportunity(
                                            name=name,
                                            stageName=stage,
                                            leadSource=source,
                                            closedate=Date.valueOf(closedate));
        insert newOpportunity;
        return newOpportunity.Id;
    }   
}

Integration in Salesforce using REST API | Standard REST API | APEX REST API | POSTMAN | DAY 9: P1

SOAP API

  • Application layer protocol used to exchange structured information between systems
  • It uses a Web Services Description Language (WSDL) file to rigorously define the parameters for accessing data through the API.
  • SOAP API supports XML only.
  • Because SOAP API uses the WSDL file as a formal contract between the API and consumer, it’s great for writing server-to-server integrations.
  • Access to Salesforce data and business logic
  • Handles medium data volumes
  • Updates multiple records with single

invocations Example: Universal Hospitality would like to update the Salesforce account records 3 times a day, if there are 5000 to 10000 records with each update

SOAP API

SOAP Message

Enterprise vs Partner WSDL


Enterprise vs Partner WSDL

SOAP vs REST

Web Services API / SOAP REST
Meaning/Uses Simple Object Access Protocol, uses WSDL Representational State Transfer, native use of all HTTP methods
Design Standardized protocol with pre-defined rules to follow. Architectural style with loose guidelines and recommendations.
Approach Function-driven (data available as services, e.g.: “getUser”) Data-driven (data available as resources, e.g. “user”).
Statefulness Stateless by default, but it’s possible to make a SOAP API stateful. Stateless (no server-side sessions).
Caching API calls cannot be cached. API calls can be cached.
Security WS-Security with SSL support. Built-in ACID compliance. Supports HTTPS and SSL.
Performance Requires more bandwidth and computing power. Requires fewer resources.
Message format Only XML. Plain text, HTML, XML, JSON, YAML, and others.
Transfer protocol(s) HTTP, SMTP, UDP, and others. Only HTTP
Recommended for Enterprise apps, high-security apps, distributed environment, financial services, payment gateways, telecommunication services. Public APIs for web services, mobile services, social networks.
Advantages High security, standardized, extensibility. Scalability, better performance, browser-friendliness, flexibility.
Disadvantages Poorer performance, more complexity, less flexibility. Less security, not suitable for distributed environments.
Error Handling SOAP response will contain error information Custom since there is no built-in

Salesforce Limits

  • How often are you making requests?
    • Limits enforced on Api usage for a given 24-hour period
    • License types and number of users
    • Enterprise – 1000 calls / license (1M call if 1000 licenses)
    • Unlimited – 5000 calls/ license
  • How big is your payload?

Integrating with Salesforce using SOAP API | Enterprise & Partner WSDL | DAY 9 Part 2

Integration Patterns

Pattern Scenario
Remote Process Invocation—Request and Reply Salesforce invokes a process on a remote system, waits for completion of that process, and then tracks state based on the response from the remote system.
Remote Process Invocation—Fire and Forget Salesforce invokes a process in a remote system but doesn’t wait for completion of the process. Instead, the remote process receives and acknowledges the request and then hands off control back to Salesforce.
Batch Data Synchronization Data stored in Lightning Platform is created or refreshed to reflect updates from an external system, and when changes from Lightning Platform are sent to an external system. Updates in either direction are done in a batch manner.
Remote Call-In Data stored in Lightning Platform is created, retrieved, updated, or deleted by a remote system.
UI Update Based on Data Changes The Salesforce user interface must be automatically updated as a result of changes to Salesforce data.
Data Virtualization Salesforce accesses external data in real time. This removes the need to persist data in Salesforce and then reconcile the data between Salesforce and the external system.

Salesforce Integration Patterns & Best Practices

Further Learning

  • Lightning Platform API Basics
  • Apex Integration Services

Assignment

Complete below assignment to win $1000 Salesforce Voucher. Click here for rule.

Expose Salesforce Object Event
Develop & Apex Rest to send the Event Details to 3rd party in JSON format. Below is the structure which needs to be send.
Note – You only need to develop the class. Need not to worry about 3rd party.
{
“Name” : “ApexHoursDev For Student”,
“Organizer” : “ApexHours”,
“Start Date” : “10-02-2020”, ( DD-MM-YYY )
“End Date” : “26-02-2020”,
“Location” : “Online”, // Location Should Contains – Street, City, State, Postal Code, Country
“Attendees” : “count here”,
“Event Number” : “EVT-00023”
}

Don’t forget to register for our next session on Part 2. Check this post for all other session detail.

Please note that we have limit of 500 attendees that can join the online sessions. However, recording will be posted on our YouTube channel. Make sure to subscribe our YouTube channel to get notification for video upload.

So, learn at your pace and free will and ace your journey to Salesforce!

23,715 total views, 27 views today

9 comments

  • Completed Assignment for Day 9

    All the fields that are mentioned(Name, Organizer etc.,) are not available on my developer org on standard Event object and hence could not get them. Was able to get the fields that are available on the Event object in the dev org.

  • assignment done.
    Not all fields were available on my org. .Could not find Attendees field in Field and Relationship settings.
    I tried to access Name as WhoId.Name, but it gave me error.

  • Name and Organizer fields are similar as WhoId.Name and OwnerId. So can we just use WhoId and OwnerId instead of Name and Organizer. Also, AttendeesField is available in page Layout to me. But not in Field and Relationship. Can you please guide me, Why does?

    Thanks!
    Arjinder Kaur

  • Hello,
    thanks for the detailed explanation

    I have a query here like – Do we use Remote site setting and Connected App while we are doing integration using SOAP Web service ?
    I have seen in your videos that while integrating Salesforce with some other app using REST web service, we use Remote site setting (if it is an outbound) and Connected app (if is an inbound).
    But while integrating using SOAP we havent used Remote site setting and Connected app.

    Please can you explain this ?

  • Chinmaya, Remote Site Settings are leveraged to whitelist an external url and make Salesforce aware. This is used when calls need to be made from Salesforce to an external app or a service.

    Connected Apps are used when external or third party services or apps intend to communicate with Salesforce. Connected Apps are used for authentication wheres Remote Site Settings are purely for whitelisting.

  • Code for Assignment Day 9
    ——————————–

    @RestResource(urlMapping = ‘/Event/*’)
    global with sharing class EventRestManager {
    @HttpGet
    global static String getEventDetailsById(){
    RestRequest request = RestContext.request;
    Integer attendees = 0;
    Map eventDetail = new Map();

    try{
    String eventId = request.requestURI.substring(request.requestURI.lastIndexOf(‘/’) + 1);
    System.debug(‘EventId:’ + eventId);

    Event event = [SELECT Id,What.Name,Owner.Name,StartDateTime,EndDate,Location,Event_Number__c,
    Account.BillingStreet,Account.BillingCity,Account.BillingState,
    Account.BillingPostalCode,Account.BillingCountry,
    (SELECT Id FROM EventRelations where IsInvitee=TRUE)
    FROM Event where id=:eventId];

    for(EventRelation relation : event.EventRelations) {
    attendees = attendees + 1;
    }

    Date dt = (Date)event.EndDate;
    String endDate = DateTime.newInstance(dt.year(),dt.month(),dt.day()).format(‘d-MM-YYYY’);

    String location = ”;
    System.debug(‘Locaion’ + String.isNotEmpty(location));
    if(String.isNotBlank(event.Account.BillingStreet) && String.isNotEmpty(event.Account.BillingStreet) && event.Account.BillingStreet != null){
    location = event.Account.BillingStreet;
    }
    if(String.isNotBlank(event.Account.BillingCity) && String.isNotEmpty(event.Account.BillingCity) && event.Account.BillingCity != null){
    location = location + ‘,’ + event.Account.BillingCity;
    }
    if(String.isNotBlank(event.Account.BillingState) && String.isNotEmpty(event.Account.BillingState) && event.Account.BillingState != null){
    location = location + ‘,’ + event.Account.BillingState;
    }
    if(String.isNotBlank(event.Account.BillingPostalCode) && String.isNotEmpty(event.Account.BillingPostalCode) && event.Account.BillingPostalCode != null){
    location = location + ‘,’ + event.Account.BillingPostalCode;
    }
    if(String.isNotBlank(event.Account.BillingCountry) && String.isNotEmpty(event.Account.BillingCountry) && event.Account.BillingCountry != null){
    location = location + ‘,’ + event.Account.BillingCountry;
    }
    System.debug(‘Locaion’ + location);
    eventDetail.put(‘Name’,event.What.Name);
    eventDetail.put(‘Organizer’,event.Owner.Name);
    eventDetail.put(‘Start Date’,event.StartDateTime.format(‘d-MM-YYYY’));
    eventDetail.put(‘End Date’,endDate);
    eventDetail.put(‘Location’,location);
    eventDetail.put(‘Attendees’,attendees);
    eventDetail.put(‘Event Number’,event.Event_Number__c);
    } catch(System.QueryException e){
    eventDetail.put(‘Error Message’,’Please Enter valid EventId’);
    }
    return System.JSON.serialize(eventDetail);
    }

    }

  • Solution: Apex Class as follow –>
    ————————————————————————————————————————————–

    @RestResource( urlMapping = ‘/Event/*’ )
    global with sharing class EventManager {
    @HttpPost
    global static ID createEvent ( String name, String subject, String loc, String stdate, String enddate ) {
    Event newEvent = new Event (
    Subject = subject,
    Location = loc,
    StartDateTime = DateTime.valueof(stdate),
    EndDateTime = datetime.valueof(enddate)

    );

    insert newEvent;
    return newEvent.Id;
    }

    @HttpGet
    global static Event getEventById() {
    RestRequest request = RestContext.request;
    String eventId = request.requestURI.substring ( request.requestURI.lastIndexof(‘/’)+1 );
    Event result = [SELECT Subject, Location, StartDateTime, EndDateTime FROM Event WHERE Id =:eventId];
    return result;

    }

    @HttpPut
    global static ID updateEventField ( ) {
    RestRequest request = RestContext.request;
    String eventId = request.requestURI.substring ( request.requestURI.lastIndexof(‘/’)+1 );
    Event thisEvent = [SELECT Id FROM Event WHERE Id =:eventId];

    //Deserilize the JSON string into name-value pairs
    Map params = (Map) JSON.deserializeUntyped ( request.requestBody.tostring() );
    // *********** Please Add String,Object within angular brackets after Map on above line of code******************

    for(String fieldName : params.keySet()){
    thisevent.put(fieldName, params.get(fieldName));
    }
    update thisEvent;
    return thisEvent.Id;

    }
    }

Leave a Reply