No comments yet

Elastic Computing without limits with Salesforce Functions

In this session we will learn about Salesforce Functions and how to start writing them from scratch. We will see how to build elastic computing without limits with Salesforce Functions.

What is a function?

A single purpose, on demand, short-lived microservice without complex infrastructure. Salesforce Functions is a service that lets developers write code that integrates with data and events on the Salesforce Platform.

Introducing Salesforce Functions

Scale elastically on trusted infrastructure : Meet any business need with functions that run on demand and scale elastically.

Innovate with flexibility : Deliver business value faster with native access to Salesforce data & languages such as Node.js and Java.

Deliver connected digital experiences : Empower your team to build integrated solutions with low-code and code

Introducing Salesforce Functions
Introducing Salesforce Functions

What makes them great

Elastic Scale : Extend Salesforce data with elastic compute that scales on demand.

Stay on Platform : Build with pre-configured secure access to C360 data.

Expand Talent Pool : Extend Salesforce data with elastic Build inclusively with all your developer talent using open languages and tools that scale on demand.

When to use Functions

When to use Functions
When to use Functions

Anatomy of a Function (JS)

Each JavaScript Function exports an async function this is where all of the works is done.

module.exports = async function (event, context, logger) {
 //Do Something
}

Each function has access to the event, context, & logger objects

  • The event contains the payload that was passed into the function
  • The context allows access to an authenticated Org and the Salesforce SDK
  • The logger helps you log right from your function

Anatomy of a Function (Java)

Each Java Function implements a SalesforceFunction<Input,Output> interface.

public class JavaFunction implements SalesforceFunction<FunctionInput, FunctionOutput> {
  private static final Logger LOGGER = LoggerFactory.getLogger(JavaFunction.class);
  @Override
  public FunctionOutput apply(InvocationEvent<FunctionInput> event, Context context)
      throws Exception {
     // Do something
  }
}

Each function has access to the event & context, the LOGGER is a standard Java log4j instance.

The event contains the payload that was passed into the function

The context allows access to an authenticated Org and the Salesforce SDK

Invoking Functions (Sync)

Functions can be invoked directly from Apex. You can use the functions.Function class to get a function reference and invoke it by passing it a JSON payload.  You can then get the response from the functions.FunctionInvocation object.

You can invoke them synchronously and asynchronously.

public with sharing class GenericFunctionInvoker {
  public static String invoke(String functionName, String payload) {
    functions.Function function = functions.Function.get(functionName);
    functions.FunctionInvocation invocation = function.invoke(payload);
    String response = invocation.getResponse();
    return response;
  }
}

An async invocation receives a callback, which inherits from functions.FunctionCallback

public with sharing class GenericFunctionInvoker {
  public static void invoke(String functionName, String payload) {
    functions.Function function = functions.Function.get(functionName);
    functions.FunctionInvocation invocation = function.invoke(payload, new MyCallback());
  }

  public class MyCallback implements functions.FunctionCallback {
    public void handleResponse(functions.FunctionInvocation invocation) {
      String response = invocation.getResponse();
    }
  }
}

Salesforce SDK for Node.js Functions

The Salesforce SDK is the gateway to your Salesforce data and org information through a number of interfaces.

  • Context
  • Data API
  • Org
  • Unit of Work
  • User
  • & more

Context > Org Interface. Get access to information about the attached Salesforce Org and access to the Data API and User Interfaces.

module.exports = async function (event, context, logger) {
  const orgInfo = {
        id: context.org.id,
        apiVersion: context.org.apiVersion,
        baseUrl: context.org.baseUrl,
        domainUrl: context.org.domainUrl
    }
    logger.info(JSON.stringify(orgInfo));
    return orgInfo;
}

Context > Org > User Interface : Get access to information about the attached Salesforce User

const userInfo = {
  id: context.org.user.id,
  onBehalfOfuserId: context.org.user.onBehalfOfuserId,
  username: context.org.user.username
}
logger.info(JSON.stringify(userInfo));
return userInfo;

Context > Org > Data Api Interface : Query, Create, Update & Delete Salesforce Data

const results = await context.org.dataApi.query(
  `SELECT Id, (SELECT Name, Email FROM Contacts) FROM Account WHERE Name LIKE '%${keyword}%'`
);
logger.info(JSON.stringify(results));
return results;

Context > Org > Data Api Interface : Query, Create, Update & Delete Salesforce Data

const results = await context.org.dataApi.create(
  type: "Account",
  fields: {
    Name: payload.accountName
  }
);
logger.info(JSON.stringify(results));
return results;

Context > Org > Data Api > Unit of Work Interface : Batch together multiple CRUD operations in a single transaction

const uow = context.org.dataApi.newUnitOfWork();
const accountId = uow.registerCreate({
  type: "Account",
  fields: {
    Name: payload.accountName
  }
});

const contactId = uow.registerCreate({
  type: "Contact",
  fields: {
    LastName: payload.lastName,
    AccountId: accountId // Get the ReferenceId from previous operation
  }
});
const caseId = uow.registerCreate({
  type: "Case",
  fields: {
    subject: payload.subject,
    Description: payload.description,
    AccountId: accountId, // Get the ReferenceId from previous operation
    ContactId: contactId // Get the ReferenceId from previous operation
  }
});
// Commit Unit of Work operation
const response = await context.org.dataApi.commitUnitOfWork(uow);

Recording

Further Learning

Check out the our YouTube, and don’t forget to subscribe to our channel, so that you’re notified right away when a new video is available.

Post a comment