Salesforce CORS JSONP

In this blog, I am going to explain how to solve CORS in Salesforce  by using JSONP( JSON Padding ) 

What is CORS?

CORS introduces a standard mechanism that can be used by all browsers for implementing cross-domain requests. The spec defines a set of headers that allow the browser and server to communicate about which requests are (and are not) allowed.Cross-Origin Resource Sharing (CORS) allows us to use Web applications within browsers when domains aren’t the same. For example, a site with domain wants to execute x.org AJAX requests to a Web application with the domain y.org using HTTP.
                        For security reasons, browsers restrict cross-origin HTTP requests initiated from within scripts. For example, XMLHttpRequest and Fetch follow the same-origin policy. So, a web application using or XMLHttpRequest Fetch could only make HTTP requests to its own domain.

               The Cross-Origin Resource Sharing standard works by adding new HTTP headers that allow servers to describe the set of origins that are permitted to read that information using a web browser.  Additionally, for HTTP request methods that can cause side-effects on server’s data (in particular, for HTTP methods other than GET, or for POST usage with certain MIME types), the specification mandates that browsers “preflight” the request, soliciting supported methods from the server with an HTTP OPTIONS request method, and then, upon “approval” from the server, sending the actual request with the actual HTTP request method. Servers can also notify clients whether “credentials” (including Cookies and HTTP Authentication data) should be sent with requests.

What is JSONP?

JSONP is JSON Padding is technology that enables Sharing of data bypassing Same-origin policy. The policy disallows running JavaScript to read media DOM elements or XHR data fetched from outside the page’s origin In JSONP  a server must reply with a response that includes the JSONP function. JSONP does not work with JSON-formatted results. The JSONP function invocation that gets sent back, and the payload that the function receives, must be agreed upon by the client and server.

For Examples in this script, parseResponse is the function which will return as part of the script invocation 

http://server.example.com/Users/1234?callback=parseResponse

In this example, the received payload would be: parseResponse({“Name”: “Foo”, “Id”: 1234, “Rank”: 7}); because Javascript called via the tagscript isn’t subject to the browser’s same-origin policythe response will simply be executed in the browser with our parseResponse function.

Breaking it all down

The core elements of JSONP, then, are as such:

  1. A callback function defined on your site.
  2. A request to the remote API via <script> tag:
    • Includes a special param providing the name of your callback function
  3. The response:
    • Is just Javascript
    • That consists of:
      • A function call, the name of which you specified in the request
      • With the argument being the JSON data of interest
    • Gets executed immediately, as if it were called from your own domain

Let’s test now:-


Create a visualforce page with the following code. 

<apex:page showHeader="false" standardStylesheets="false">
    https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js
    
    <script type = "text/javascript" language = "javascript">
    $(document).ready(function() {
        $("#btn").click(function(event){
            $.getJSON('https://api.flickr.com/services/feeds/photos_public.gne?tags=monkey&tagmode=any&format=json', function(jd) {
                $('#stage').html('<p> Name: ' + jd.description + '</p>');
            });
        });
        
    });
    </script>
    <body>
        
        <p>Simple JSON File to show the Demo .</p>
        
        <div id = "stage" style = "background-color:#cc0;">
            Data Will be loaded 
        </div>
        
        <input type = "button" id = "btn" value = "Load Data" />
        
    </body>
</apex:page>

Now after loading the page, go to console you will see an error message as shown below.

Now Replace the above code with the below code which is having JSONP logic 

<apex:page showHeader="false" standardStylesheets="false">
    https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js
    
    <script type = "text/javascript" language = "javascript">
    $(document).ready(function() {
        $("#btn").click(function(event){
            var script=document.createElement('script');
            script.type='text/javascript';
            script.src='https://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=processJSON&tags=monkey&tagmode=any&format=json';
            $("body").append(script);
        });
        
    });
    var processJSON = function (json) {
        console.log('json'+json);
        for (var item in json.items) {
            $('#stage').html(item);
            
        }
        
    };
    </script>
    
    <body>
        
        <div id = "stage" style = "background-color:#cc0;">
            Data Will be loaded 
        </div>
        
        <input type = "button" id = "btn" value = "Load Data" />
        
    </body>
</apex:page>

Now if you can go and see the console, you will not see any error message.

 

Salesforce REST API Composite Resources

In this blog, I am going to explain salesforce rest API composite resource which is designed to reduce the number of round trips to the server.  A composite API is a sequence of tasks that run synchronously and  Composite API is built by combing the existing API functions that can perform the multiple tasks in the single call. Salesforce composite resources contain Composite, Tree, batch resources.

A composite API may be used :

  • To speed up the execution of a sequence of tasks instead of making separate calls
  • To compose an API by creating a sequence of web services
  • Composite API run synchronously

Salesforce provides three composite resources namely composite, batch, tree
composite/: Executes a series of REST API requests in a single call. You can use the output of one request as the input to a subsequent request.
composite/batch/: Execute a set of subrequests in a single request. Subrequests are executed independently and information can’t be passed between subrequest calls.
composite/tree/: Creates one or more sObject trees with root records of the specified type. An sObject tree is a collection of nested, parent-child records with a single root record.

Composite Resource 
Composite Resource Executes a series of REST API requests in a single call. You can use the output of one request as the input to a subsequent request. .The requests in a composite call are called subrequests. All subrequests are executed in the context of the same user. In a subrequest’s body, you specify a reference ID that maps to the subrequest’s response. You can then refer to the ID in the URL or body fields of later subrequests by using a JavaScript-like reference notation. Let us consider you wanted to create a work order and work order items on the same call.The following examples contain two subqueries where the first request creates a work order and for the second request, we will pass create a work order items where we will pass the referenceId on the first request.

 

Salesforce REST API Recently Viewed Items

In this blog, I am going to explain how to use the salesforce rest API recently viewed the resource. You can able to access the recently viewed data by using even SOQL querying on the RecentlyViewed object or by Using REST API or by using LastViewedDate field with SOQL where clause.A record is considered viewed when the user sees the details associated with it, but not when the user sees it in a list with other records.Use this query in your code to retrieve a list of all the records that were recently viewed.

SELECT Id, Name FROM RecentlyViewed

Salesforce stores information about record views in the interface and uses it to generate a list of recently viewed and referenced records, such as in the sidebar and for the auto-complete options in search.

You can get the Recently Viewed Records by using /services/data/v41.0/recent rest resources.

 Below is the apex class
public class RecentlyViewController {
    @AuraEnabled
    public static List<RecenlyViewWrapper> getRecentItems(){
        List<RecenlyViewWrapper> warpperlist = new List<RecenlyViewWrapper>() ; 
        Http h = new Http();
        HttpRequest httpReq = new HttpRequest();
        httpReq.setMethod('GET');
        httpReq.setEndpoint('callout:REST_API1/services/data/v37.0/recent/?limit=200');
        HttpResponse res = h.send(httpReq);
        List<RecenlyViewWrapper> recentItemsList =
            (List<RecenlyViewWrapper>)JSON.deserialize(res.getBody(), List<RecenlyViewWrapper>.class);
        system.debug('recentItemsList'+recentItemsList.size());
        return recentItemsList ;
    }
    public class RecenlyViewWrapper{
        @AuraEnabled
        public String Id {get; set;}
        @AuraEnabled
        public String Name {get; set;}
         
    }
    
}

Here the below Lightning Component.

<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes" access="global" controller="RecentlyViewController">
    <aura:attribute name="recentItems" type="List"/>
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    <table class="slds-table slds-table--bordered">
        <tbody>
            <aura:iteration items="{!v.recentItems}" var="recentItem">
                <tr>
                    <td> 
                        <ui:outputURL value="{!recentItem.Id}" label="{!recentItem.Name}">  </ui:outputURL>
                    </td>
                </tr>
            </aura:iteration>
        </tbody>
    </table>
</aura:component>

Component Controller

({
    doInit : function(component, event, helper) {
        helper.getRecentItems(component);
        
    } , 
   
})

Component helper

({
    getRecentItems : function(component) {
        var action = component.get("c.getRecentItems");
        action.setCallback(this, function(a) {
            component.set("v.recentItems", a.getReturnValue());
        });
        $A.enqueueAction(action);
    }
})

 

 

Salesforce Rest API Limits Pie Chart Component

In this blog, I am going to show how to create a simple lightning component pie chat to visualize the salesforce limits by using salesforce rest API. I am going to use d3 js and d3pie to built the lightning component. refer more to d3 pie js here.

Step 1: Create a salesforce connected app as shown below. We need to create a named credential to authenticate the web service call. Go to setup –> create apps–> create a new connected app as shown below and save it to get consumer key and secret key. In this step use any URL as callback URL. later after confirmed the auth provides we will replace the callback URL from auth provider callback URL

After saving the connected app you will get consumer key and consumer secret which we will use to configure the Auth provides.

Step 2: Now we need to create an auth provide as shown below. Go to setup –> administration  –> Security control -> create a new Auth provide as shown below .

Replace the connected App callback URL with Auth provide callback URL

Step 3: Create a named credentials as shown below.

Step 4: Create an Apex Class

public class LimitsController {
    @AuraEnabled
    public static List<LimitsWrapper> getLimits(){
        List<LimitsWrapper> warpperlist = new List<LimitsWrapper>() ; 
        Http h = new Http();
        HttpRequest httpReq = new HttpRequest();
        httpReq.setMethod('GET');
        httpReq.setEndpoint('callout:REST_API1/services/data/v37.0/limits/');
        HttpResponse res = h.send(httpReq);
        System.debug('res'+res);
        Map<String, Object> root = (Map<String, Object>)JSON.deserializeUntyped(res.getBody());
        System.debug('root'+root.keySet());
        for(String keys : root.keySet()){
            Map<String, Object> i = (Map<String, Object>)root.get(keys);
            Decimal percentage = Decimal.valueOf(String.valueOf(i.get('Remaining')))*100 /  Decimal.valueOf(String.valueOf(i.get('Max')));
            LimitsWrapper wrap = new LimitsWrapper();
            wrap.groupName = keys ; 
            wrap.usedPercentage = percentage.setScale(2) ; 
            warpperlist.add(wrap);
        }
        return warpperlist ;
    }
    public class LimitsWrapper{
        @AuraEnabled
        public Double usedPercentage {get; set;}
        @AuraEnabled
        public String groupName {get; set;}
    }
    
}

Step 5: Create a Lightning component

<aura:component implements="flexipage:availableForAllPageTypes"
                access="global"
                controller="LimitsController">
    <b> PIE CHART </b>
    <ltng:require scripts="{!join(',',
                           $Resource.d3pie + '/d3pie/d3.min.js',
                           $Resource.d3pie + '/d3pie/d3pie.min.js')}"
                  afterScriptsLoaded="{!c.doInit}"/>
    
    <div class="slds-card__body">
        <div id="pieChart"></div>
    </div>
    
</aura:component>

Controller.js

({
    doInit: function (cmp, event, helper) {
        helper.load(cmp);
    },
  })

Helper.js

({
    load: function(cmp) {
        var action = cmp.get("c.getLimits");
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS"){
                var limits = response.getReturnValue();
                var arr = [];
                limits.forEach((key, value) => {
                    arr.push({
                    "label": limits[value].groupName,
                    "value": limits[value].usedPercentage
                });
            });
            console.log(arr);
            var pie = new d3pie("pieChart", {
                "header": {
                    "title": {
                        "text": "Salesforce Limits Pie Chart",
                        "fontSize": 34,
                        "font": "courier"
                    },
                    "location": "pie-center",
                    "titleSubtitlePadding": 10
                },
                "size": {
                    "canvasWidth": 790,
                    "pieInnerRadius": "95%",
                    "pieOuterRadius": "70%"
                },
                "data": {
                    "sortOrder": "label-desc",
                    "content": arr
                },
                "labels": {
                    "outer": {
                        "format": "label-percentage1",
                        "pieDistance": 20
                    },
                    "inner": {
                        "format": "none"
                    },
                    "mainLabel": {
                        "fontSize": 11
                    },
                    "percentage": {
                        "color": "#999999",
                        "fontSize": 11,
                        "decimalPlaces": 0
                    },
                    "value": {
                        "color": "#cccc43",
                        "fontSize": 11
                    },
                    "lines": {
                        "enabled": true,
                        "color": "#777777"
                    },
                    "truncation": {
                        "enabled": true
                    }
                },
                "effects": {
                    "pullOutSegmentOnClick": {
                        "effect": "linear",
                        "speed": 400,
                        "size": 8
                    }
                },
                "misc": {
                    "colors": {
                        "segmentStroke": "#000000"
                    }
                }
            });
            
        } else if(state == "ERROR"){
            var errors = response.getError();
            console.log(errors);
        }
        
    });
    $A.enqueueAction(action);
},
 
 })

 

Finally, the component output pie chart looks as shown below.