Sunday, 15 August 2021

Salesforce Composite resources/Composite API

 REST API composite resources are helpful to improve application's 

performance by minimizing the number of round-trips between the client and server.


what is Composite resources ?


Composite resources is an enhanced form of rest api which executes a series of rest api

requests in a single call.


It helps you to do multiple operations like read, create, update and delete salesforce data in single callout.


Note :

you can use output of one request as the input to a subsequent request response bodies and status of all these rest api 

requests are together returned in a single response body.


All the series of rest apis are counted as a single call towards your API limits.This is executed in the context of the same user.


1.Series of REST API requests in a single call.

2.Multiple CRUD Operations.

3.Output of one request as the input to a subsequent request.

4.Response bodies and status in a single response body.

5.Counts as a single call towards your API limits.

6.Executed in context of the same user.


Composite Resources consists of 


1.URI : /vxx.x/composite

2.Formats - JSON

3.HTTP method- GET,POST

4.Authorization : Bearer token

5.Composite Request Body

6.Composite Response Body



Composite request body :


{

   "allOrNone" : true,

   "collateSubrequests": true,

   "compositeRequest" : [

     { Composite Subrequest},

     { Composite Subrequest},

     { Composite Subrequest}

   ]

}


Composite request response :


{

   "compositeResponse" : [

      {  Composite Subrequest Result },

      {  Composite Subrequest Result },

      {  Composite Subrequest Result }

   ]

}



Why Composite Resources

Lets understand the advantage of composite API.


1.Multiple REST API calls for single call

2.Processing speed can be made faster by collating the subrequests.

3.Improves the performance of the application

4.No additional coding required at Salesforce. 

5.Single call toward API limits.

6.Synchronous responses.

7.Multiple ways in composite resources work.

8.Upsert upto five levels deep relationships.

9.Flexible on upserting related or non related records.

10.Can do a GET subrequest and the result can be input to next POST subrequest.

11.Can handle more complicated and related objects and data. 



Types of Composite Resources :


1.Composite API

2.Batch

3.SObject Tree

4.SObject Collection

5.Grapths

Thursday, 24 June 2021

Salesforce CLI Unification

 Salesforce introduced a new global CLI executable called sf 

 that provides you with a single command line taxonomy for cross-Salesforce development.

 

 Salesforce CLI Unification unify all of Salesforce's product under one CLI.


 Salesforce CLI goal is to provide a seamless developer experience when building applications

 on any salesforce product as well as across products.


 CLI Unification is an effort designed to eliminate tool and context switching.

 

  ex :

  

  sf project deploy by default deploys the entire project that is defined in your local directory. 

  If your project includes Functions and a Force app, then both are deployed to their respective environments.

  

  Let’s say that you later include a Heroku app, some MuleSoft APIs, and a resource from Marketing Cloud in your project. 

  In this case, sf project deploy will deploy all of these resources to all of the respective environments.

  

  

  You can use the product-specific project deploy commands that have flag options for granular deployment.

  

  ex :

   sf project deploy org will support all the current options for force:source:deploy and force:source:push.

   

  To install the Demo CLI with npm, run the following from your terminal:

  

  npm install --global @salesforce/sf-demo

  sf --help 


  Usefull Commands : 

  

  sf --help         : shows the top-level topics and commands. 

  sf project --help : shows the subtopics and commands under project.

  

    sf config get

    sf config list

    sf config set

    sf config unset

    sf data data

    sf env alias set [ALIAS]

    sf env alias unset [ALIAS]

    sf env create compute [ENVNAME]

    sf env create org [ENVNAME]

    sf env display

    sf env list

    sf env log get

    sf env log list

    sf env log tail

    sf env logdrain add

    sf env logdrain list

    sf env logdrain remove

    sf env open

    sf env usage

    sf env var get

    sf env var list

    sf env var set

    sf env var unset

    sf event event

    sf generate analytics template

    sf generate apex class

    sf generate apex test

    sf generate apex trigger

    sf generate community

    sf generate function

    sf generate lightning component

    sf generate lightning event

    sf generate lightning interface

    sf generate project

    sf heroku heroku

    sf login

    sf login functions

    sf login org

    sf login org jwt

    sf logout

    sf logout org

    sf package package

    sf plugins

    sf plugins:inspect PLUGIN...

    sf plugins:install PLUGIN...

    sf plugins:link PLUGIN

    sf plugins:uninstall PLUGIN...

    sf plugins update

    sf project deploy

    sf project deploy functions

    sf project deploy org

    sf project retrieve

    sf project retrieve org

    sf reset

    sf run apex

    sf run function

    sf run function start

    sf test apex

    sf test function

    sf usage

    sf whoami

Tuesday, 22 June 2021

process a large amount of records in serial chunks using Queueables


/**

 * @description A demonstration recipe for how to process a large amount of

 * records in serial chunks using Queueables. The idea behind this recipe

 * is that Queueables, in production, have no max-queue depth. Meaning that so

 * long as you only enqueue one new queueable, it can keep cycling through until

 * the entire data set is processed. This is useful for instance, when you want

 * to process hundreds of thousands of records.

 *

 * Note: You're not able to re-enqueue within a test context, so the unit test

 * for this code is limited to the same number of records as chunkSize below.

 *

 * Note: This should be refactored to be an abstract class that you can extend

 * named 'Ouroboros'. (Ouroboros = the snake eating it's own tail)

 *

 * @group LDV Recipes

 */

public with sharing class LDVRecipes implements Queueable {

    private final Integer chunkSize = 20;

    private Id offsetId;

    private List<ContentDocumentLink> objectsToProcess;

    @testVisible

    private static Integer chunksExecuted = 0;


    /**

     * @description No param constructor. Use for starting the chain.

     */

    public LDVRecipes() {

        this.objectsToProcess = getRecordsToProcess(this.offsetId);

    }


    /**

     * @description    Constructor accepting an ID to use as an offset. Use

     * this version to *continue* the chain.

     * @param offsetId

     */

    public LDVRecipes(Id offsetId) {

        if (offsetId != null) {

            this.offsetId = offsetId;

        }

        this.objectsToProcess = getRecordsToProcess(this.offsetId);

    }


    /**

     * @description            This method contains the 'what' happens to each

     * chunk of records. Note, that this example doesn't actually do any

     * processing. In a real-life use case you'd iterate over the records stored

     * in this.objectsToProcess.

     * @param queueableContext

     */

    public void execute(System.QueueableContext queueableContext) {

        // Used to demonstrate the method was executed.

        LDVRecipes.chunksExecuted += 1;

        // If you're processing the group of records there's likely a better way

        // to determine the last objects' id, but this will do for demonstrating

        // the idea. We need the last id from objectsToProcess in order to

        // construct the next queueable with an offset.

        Id lastRecordId = objectsToProcess[objectsToProcess.size() - 1].id;


        if (getRecordsToProcess(lastRecordId).size() > 0 && safeToReenqueue()) {

            LDVRecipes newQueueable = new LDVRecipes(lastRecordId);

            System.enqueueJob(newQueueable);

        }

    }


    /**

     * @description    Returns a 'cursor' - a set of records of size X from a

     * given offset. Note: We originally intended to use OFFSET - the SOQL

     * keyword, but discovered the max OFFSET size is 2000. This obviously won't

     * work for large data volumes greater than 2000 so we switched to using the

     * ID of the record. Since ID is an indexed field, this should also allow

     * us to prevent full table scans even on the largest tables.

     * @param offsetId The offset id is used to demarcate already processed

     * records.

     * @return         `List<ContentDocumentLink>`

     */

    private List<ContentDocumentLink> getRecordsToProcess(Id offsetId) {

        String queryString = '';

        queryString += 'SELECT ContentDocumentId,ContentDocument.Title, ContentDocument.CreatedDate,LinkedEntityId ';

        queryString += 'FROM ContentDocumentLink ';

        queryString += 'WHERE LinkedEntityId in (SELECT Id FROM Account) ';

        if (offsetId != null) {

            queryString += 'AND ID > :offsetId ';

        }

        queryString += 'WITH SECURITY_ENFORCED ';

        queryString += 'ORDER BY ID ASC ';

        queryString += 'LIMIT :chunkSize';

        return Database.query(queryString);

    }


    private Boolean safeToReenqueue() {

        return Limits.getLimitQueueableJobs() > Limits.getQueueableJobs();

    }

}

Monday, 21 June 2021

Salesforce Integration API's

No-code Integrations :

=====================


MuleSoft

Salesforce Connect

Heroku Connect

External Services


Custom API Integrations :

=========================


SOAP

REST

Bulk

Composite

Streaming 

metadata

Tooling 

UI


Streaming Events Integrations (pub/Sub) :

=========================================


Platform Events

Change Data Capture


Salesforce Platform Integration Features :


1.Salesforce Core


APIs and Web Services

Salesforce Connect

External Services

Event Bus


2.Heroku 


Database

Heroku Connect

Other add-ons

Compute Dynos


3.Mulesoft Anypoint


Connectors

API Design & Mgt

Integration Runtime

Secure API Gateway


Salesforce Core APIs :

======================

1.REST API

  Access and manipulate data with a RESTful pattern using JSON and XML.

2.SOAP API

  Access and manipulate data using standard SOAP XML messages

3.Bulk API

   Perform large volume CRUD operations asynchronously.

4.Composite Graph API

   Chain multiple operations for related objects/records in a single REST call.

5.APEX (Custom SOAP and REST API using Apex Programming language)

   Build custom SOAP and REST APIs through Apex programming language.

6.Streaming API

   Subscribe to events using the Bayeux/CometD HTTP long-polling protocol.

7.User Interface API.

   Return UI-optimized payload display,edit or create a record.

8.Industries API

   Access to special Health and Financial Services Cloud-specific objects and features.

9.Analytics API

  Access Salesforce Report and Dashboard data using Restful APIs.

10.Metadata API

   Package and deploy setup metadata to Salesforce orgs asynchronously.

11.Tooling API

   Build custom development tools for applications using SOAP and RESTful APIS.

12.Social API 

   View,create and join Chatter conversations through RESTful APIs

   


Data APIs(SOAP & REST) :


Access and modify objects and records in real-time


ex : /SObjects/Account

     /SObjects/Account/describe

     /query?q=SELECT+Name,Industry+FROM+Account

     

     /SObjects/Property__c

     /SObjects/Property__c/describe

     /query?q=SELECT+Name,Type__c+FROM+Property__c

     /query?q=SELECT+FIELDS(ALL)+FROM+Property__c+LIMIT+200

     

Bulk API :


Access and modify large number of records asynchronously.

SOAP & REST are real-time APIs so daily limits apply.

Bulk API lets you process up to millions of records asynchronously.

Based on REST,Processes operations in batch.


Configure and start --> Check job Status --> Retrieve results.


Composite Graph API :


Chain multiple CRUD operations for related objects/records in a single REST call.

Requests organized in a graph.

Designed for optimal processing.

Ability to roll back entire transaction.


Apex Callout (HTTP Request) :


HttpRequest req=new HttpRequest();

req.setEndpoint(url);

req.setMethod(method);

req.setBody(body);

Http http =new Http();

HttpResponse resp=http.send(req);


Custom Apex REST Endpoint :


@RestResource(urlMapping='/propertyhub/*)

global class PropertiesService{

  @HttpGet

  global static void getAccounts(){

    RestRequest req = RestContext.request;

    RestResponse res = RestContext.response;

    

    //Do something with request

    // Send a custom response or return data (serialized as JSON)

      try {

            List<Account> accounts = [SELECT Id, Name FROM Account];

            res.responseBody = Blob.valueOf(JSON.serialize(accounts));

            res.statusCode = 200;

        } catch (Exception e) {

            res.responseBody = Blob.valueOf(e.getMessage());

            res.statusCode = 500;

        }

  

  }

 

}     


Design with the Right API :


SOAP : server to server , real-time access

REST : Client to Server, real-time access

Bulk : Working asynchronously with large data volumes

Composite API : Set of operations related objects/records

Custom APex REST & SOAP : Exposing custom business logic.


Salesforce Connect :


1.OData 2.0/4.0 or Custom Connector using Apex.

2.External data represented as Salesforce entites/objects.

3.Setup & sync with no code.

4.No data duplication

5.Data mastering at system of record.


Heroku Connect :


Salesforce data synchronized to a Heroku Postgres database.


External Service :


Integrate with 3rd party systems without code.

1.Import an ApenAPI specification schema.

2.Select operations

3.Use auto-generated Flow Actions.


Streaming API :


1.Change Data Capture(streaming event)

2.Platform Events


1.Change Data Capture(streaming event) :


A Change Data Capture event, or change event, is a notification that Salesforce sends 

when a change to a Salesforce record occurs as part of a create, update, delete, or undelete operation. 

The notification includes all new and changed fields, and header fields that contain information about the change. 

For example, header fields indicate the type of change that triggered the event and the origin of the change. 

Change events support all custom objects and a subset of standard objects.


Use change events to:


1.Receive notifications of Salesforce record changes, including create, update, delete, and undelete operations.

2.Capture field changes for all records.

3.Get broad access to all data regardless of sharing rules.

4.Get information about the change in the event header, such as the origin of the change, 

  which allows ignoring changes that your client generates.

5.Perform data updates using transaction boundaries.

6.Use a versioned event schema.

7.Subscribe to mass changes in a scalable way.

8.Get access to retained events for up to three days.


Asynchronous Apex triggers :


Asynchronous Apex triggers are change event triggers that run asynchronously after a database transaction is completed. 

They are ‘after-insert’ triggers and can be created the same way you create regular Apex triggers, the only difference is the sObject,

where you will have change it to the event object. The name of changeEvent object has suffix “changeEvent” for standard object and   

__changeEvent for custom objects (e.g. OpportunityChangeEvent , Employee_ChangeEvent  etc).


Use of Asynchronous trigger and Change Data Capture. 


1. Asynchronous triggers are the probable replacement for future methods and queuable 

    jobs with certain limitations.  


2. Let’s take a simple business example: when a customer logs a case with customer 

    service, case records gets created. If you want write a logic which can execute 

    asynchronously and assign a technician to it then you can write an asynchronous trigger 

    on CaseEvent.


3. Change Data Capture can be used for Integration purpose such as to downstream 

    system (ERP System) and it is much more effective and faster than the normal 

    webservices.  


4. CDC stores events up to 3 days so very effective if your downstream system is down for 

     weekly maintenance, it will automatically re trigger once it is up.  


2.Platform Events :


Platform events enable you to deliver secure, scalable, and customizable event notifications within Salesforce 

or from external sources via a Message bus.


MuleSoft :


Build Low Code Integrations with MuleSoft.


Integrate fast with Flow Designer.

Rich set of built-in connectors.

Low code be extended with script.

More than just a builder, a run-time manager.


Sunday, 13 June 2021

Multi-Currency in Salesforce

 1.Currency controls display of currency, such as currency symbols, period/comma for decimal places.

2.All objects that have currency field will have CurrencyIsoCode field to specify the currency that is used (available in multi-currency org)

3.In SOQL, convertCurrency() function can be used to convert currency and format() function 

can be used in SOQL to format number, date, time, fields based on user's locale, 

ex: SELECT format(convertCurrency(Amount)) from Opportunity

Saturday, 12 June 2021

Canvas app in Salesforce

 Canvas allows developers to connect existing legacy system or any web-based application with Salesforce

using javascript and REST API.Canvas applications can be displayed in chatter,Salesforce Mobile Cards or Visualforce Page.


ex :


<apex:page controller="JSONGeneratorSample">

    <apex:canvasApp developerName="mycanvas" parameters="{!generateJSON}" />

</apex:page>


<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes" access="global" >

    <div class="canvas-container">

        <force:canvasApp developerName="mycanvas" height="1200px"/>

    </div>

</aura:component>



Canvas App in Salesforce :


Canvas enables you to easily integrate a third-party application in Salesforce.

Canvas is a set of tools and javascript APIs that you can use to expose an application as a canvas app.

This means you can take your new or existing applications and make them available to your users as part of their Salesforce experience.


Canvas App Previewer :


Canvas App Previewer is a development tool that lets you see what your canvas apps will look like before you publish them.


Note :

The third-party app that you want to expose as a canvas app can be written in any language.

The only requirement is that the app has a secure URL (HTTPS).


Important Entity :


1.Authentication

2.Context

3.Cross-domain XHR

4.Events

5.Canvas Apps in Visualforce


canvas app is also a kind of connected app.you can consider canvas app as connected app 

with some enhanced features to make it work seamlessly with external apps within Salesforce UI.

Some of these additional features are :


1.canvas app settings has 'Access Method' option which simplifies the way your connected app is 

getting authenticated and authorized. This is important when you want to have your canvas app do 

aurhentication and authorization behind the scene without having user know about it.


2.Canvas app frameowork provides LightWeight and easy-to-use javascript libraries.


3.Canvas app frameowork natively provides 'Context Services' which tells more about the logged-in user,

what org are they in,how much area does the canvas provide to display etc.


4.It natively allows cross-domain API calls.


5.It is based on lightweight JSON eventing frameowork which allows your app to publish and 

subscribe to events.(the events are sent through Canvas API).


Important Parameters :


Authentication - signed request or OAuth 2.0.

Context

Cross-domain cross-domain XML HTTP requests

Resizing -M

Events - Events prvide a javascript-based way to send and receive events between canvas apps.

Canvas Apps in Aura

Canvas Apps in Visualforce

Canvas Apps in the publisher

Canvas Apps in the Chatter Feed

Canvas in the Salesforce Mobile App


Canvas can be placed in Salesforce :


1.Chatter feed

2.Chatter tab

3.Console

4.Visualforce Page 

5.Layouts and Mobile Cards

6.Mobile Nav

7.Open CTI

8.Publisher


Authentication and Permission :


1.Permission

"Customize Application"

"Modify All Data"

2.Authentication

1.Signed request

2.Oauth2.0



How does canvas work ?


1.User clicks on the application from a chatter tab or Visualforce Page.

2.A signed Post request is sent to the external application.

3.External application decodes signed request,obtaining canvasRequest object.

4.External application returns HTML that is loaded into the Salesforce UI.

5.User interacts with external application page within Salesforce.

6.External application page calls out to containing frame's javascript SDK.containing page calls Salesforce.

7.External application interacts through standard APIs.


Note :

1.Canvas apps are loaded into salesforce through an iframe.

2.with canvas you can use a secure communication protocol via javascript to communicate with salesforce.


Access method :


The Force.com Canvas Framework provides authentication into salesforce.


1.Signed Request(POST)

2.OAuth Webflow (GET)


CanvasLifecycleHandler:


Note :

Apex LifeCycle Handler : Controlling your Force.com Canvas context.


Customizing the Canvas Signed Request :


Signed Request : Delivering Context to your App.

The signed request is the default (and recommended) access method.


when you click the Canvas app, we Post a signed equest to your endpoint.

Context contains data like :


1.Client information

  OAuth Token,Refresh Token,Oauth login URLs

2.User Information 

  Name,Username,ID,Email etc

3.Organization Information 

   Name,ID,MNamespace etc.

4.Environment Information 

   Dsiplay Location,Dimensions,Parameters,Record info etc.

5.Version Information

6.Useful Links


Controlling Signed Request using CanvasLifecycleHandler :


1. Using Apex to control your signed request.

2.Apex class is associated with the Canvas App.

3.You can control

-> Remove certain Signed Elements.

-> Customizing Parameters/Customize Record Fields.

-> Customizing the Canvas URL

-> Custom Error Handling

   

ex 

public class MyCanvasListener implements Canvas.CanvasLifecycleHandler{

    

    public Set<Canvas.ContextTypeEnum> excludeContextTypes(){

       Set<Canvas.ContextTypeEnum> excluded = new Set<Canvas.ContextTypeEnum>();

        excluded.add(Canvas.ContextTypeEnum.ORGANIZATION);

        excluded.add(Canvas.ContextTypeEnum.USER);

        excluded.add(Canvas.ContextTypeEnum.RECORD_DETAIL);

        return excluded;

    }

    

    public void onRender(Canvas.RenderContext renderContext){

    

        Canvas.ApplicationContext app = renderContext.getApplicationContext();

        Canvas.EnvironmentContext env = renderContext.getEnvironmentContext();

        Double currentVersion = Double.valueOf(app.getVersion());

        if (currentVersion <= 5){

            throw new Canvas.CanvasRenderException('Error: Versions earlier than 5 are no longer supported.');

        }

        app.setCanvasUrlPath('/alternatePath');

        env.addEntityFields(new Set<String>{'Name','BillingAddress','YearStarted'});

        Map<String, Object> previousParams =(Map<String, Object>) JSON.deserializeUntyped(env.getParametersAsJSON());

        previousParams.put('newCustomParam','newValue');

        env.setParametersAsJSON(JSON.serialize(previousParams));

        

    }

}  


Custom Error Handling :


with the apex lifecycle handler, you can inject your own error handling.


-> Error handling logic exists inside of the apex class.

-> Error is displayed in the Canvas error handling framework.

Friday, 11 June 2021

Lightning Web Component quick actions

 Two different types of LWC Quick actions

1.Screen Actions

2.Headless Actions


Screen Actions :


Traditionally, when you click on an action in Salesforce, it will open up a modal window that you can use to display data or interact with data. 

This is exactly what you get when you are creating a Screen Action. 

You are able to take any Lightning Web Component that you have created and expose it as a quick action.


ex :

//my-action.html


<template>

</template>


//my-action.js


import { LightningElement, api } from 'lwc';

 

export default class MyAction extends LightningElement {

  @api invoke() {

    console.log('Hello, world!');

  }

}


//my-action.js-meta.xml


<targets>

  <target>lightning__RecordAction</target>

</targets>

<targetConfigs>

  <targetConfig targets="lightning__RecordAction">

    <actionType>ScreenAction</actionType>

  </targetConfig>

</targetConfigs>


Headless Actions :


Headless actions are a welcome addition to LWC capabilities. They allow you to run JavaScript directly from the click of a button through a 

Headless Lightning Web Component. This may sound familiar if you recall writing JavaScript buttons in the past. 

One of the key differences between a screen action and a headless action is that you don’t need the HTML file in your LWC.


ex :


//headless-action.js


import { LightningElement, api } from 'lwc';

 

export default class MyAction extends LightningElement {

  @api invoke() {

    console.log('Hello, world!');

  }

}


//headless-action.js-meta.xml


<targets>

  <target>lightning__RecordAction</target>

</targets>

<targetConfigs>

  <targetConfig targets="lightning__RecordAction">

    <actionType>Action</actionType>

  </targetConfig>

</targetConfigs>


Note : 

LWC Quick actions are currently only available for use on Lighting Record Pages.


Lightning Quick Action Panel :


By default, an LWC Screen Action does not have the header and footer that you normally see in a modal window. 

This gives you the opportunity to create heavily customized user interfaces. However, if you would like to create a consistent experience, 

there is a new base component for doing just that, The Lightning Quick Action Panel.


ex :


 <template>

  <lightning-quick-action-panel title="Quick Action Title">

    Body Content

    <div slot="footer">

      <lightning-button variant="neutral" label="Cancel"></lightning-button>

      <lightning-button variant="brand" label="Save"></lightning-button>

    </div>

  </lightning-quick-action-panel>

</template>


This component allows you to:


1.Set the title attribute of the component to render the title in the modal header.

2.Place the content of your action in the body.

3.Use a slot to place content in the modal footer.


Close Action Screen Event :


When you are using screen actions, you can close the modal by importing the new CloseActionScreenEvent from 'lightning/actions'.

When fired this will shut the model window if the user needs to cancel or close the quick action.


ex :

  import { CloseActionScreenEvent } from 'lightning/actions';

 

closeAction(){

  this.dispatchEvent(new CloseActionScreenEvent());

}


Headless Actions :


A headless action can be invoked by creating an invoke() method that is exposed publicly with an @api decorator. 

This is called each time the Quick Action’s button is clicked. The component is inserted into the DOM right when the record page 

is rendered so you cannot rely on any of the standard lifecycle hooks for executing the action. For example, the connectedCallback() 

is run right when the record page loads.


It is important to note that headless actions do not have the ability to prevent the user to double-click the action. 

The following code sample will show you how you can make the invoke() method asynchronous to prevent it from being called twice.

  


ex :


import { LightningElement, api } from "lwc";

 

export default class HeadlessAsync extends LightningElement {

    isExecuting = false;    

    @api async invoke() {

        if (this.isExecuting) {

            return;

        }  

        this.isExecuting = true;

        await this.sleep(2000);

        this.isExecuting = false;

    }  sleep(ms) {

        return new Promise((resolve) => setTimeout(resolve, ms));

    }

}