Salesforce Robbie Duncan Salesforce Robbie Duncan

Flow Bulkification and Apex

The ability to call Flow in bulk from Apex is a much needed enhancement that is still not implemented on the platform

For the past few weeks I’ve been working on a side project at work which involves working with Flow from Apex. I’ve learned a few interesting things that I might blog about in future but today I want to write about one annoyance, that I was aware of before, but which has now come to the fore. There is an Idea to upvote here.

There is also this more limited Idea that requests a new type of Flow specifically to allow bulkfied offload to Flow from Apex triggers. This is too limited as we will see below.

My Apex code is calling a Flow for every record that it is processing. Normally programmers on the Salesforce platform want to bulkfiy everything. We’d not like to write code like this

List<SObject> records = …;
for (SObject record: records) {
  doSomethingWithARecord(record);
}

Especially if do something involves any more SOQL or DML. This sort of thing will almost certainly scale poorly and result in governor limits exceptions. We’d like to do something like

List<SObject> records = …;
doSomethingWithRecords(records);

Where we do any DML or SOQL once acting on all the records together. This will be much more efficient as each time we make a call to the database the app server our code is running on has to talk over the network to the database server which will take some time to respond. Much better to do that once rather than 200 times!

However when calling out to Flow this is unfortunately impossible. We have the createInterview method or, if the API name of the Flow is know at build time, the direct Flow.Interview.<FlowName> method. In each case these methods create a single Flow Interview instance which takes a single set of input variables. We cannot create, or start these interviews in bulk.

We can still loop and create and start the Flow Interviews singly but as above this might be inefficient, especially if the Flow is doing SOQL or DML operations. Another option would be to pass the Flow a list of records instead of a single record and have the Flow loop. If the Flow is well constructed this could be pretty efficient but anything in the loop in the Flow won’t be bulkfiied. The Flow designer will have to take care to use collection variables to build lists to operate on in bulk, and many won’t.

However Flow does support cross interview bulkfiication. When this is triggered, for example when multiple interviews are started for a record triggered flow, actions in the interviews are actually run as a single action across all the Interview instances allow it to act in bulk. This allows the Flow author to design natural single record Flows without worrying about bulkfiication. Most Flow authors thing and build this way.

In an ideal world we could access this from Apex. We should be able to create/start multiple interviews in parallel and have them bulkfiied by the platform. Please vote for the Idea so as this might happen.

Read More
Salesforce Robbie Duncan Salesforce Robbie Duncan

Summer '23 Named Credentials for Apex Developers

What do the Summer ‘23 changes to Named Credentials mean for Apex developers and what can you still not do from Apex?

In a previous post I discussed the changes made to Named Credentials in the Summer ‘23 release of Salesforce from an Admin point of view. In this post I’ll examine what this means for the Apex Developer.

Prior to the new form of Named Credentials being introduced in Winter ‘23 there was no “native “ way for Apex developers to interact with Named Credentials (beyond using them in callouts) - named credentials could not be created, modified or deleted from a native Apex API. It was possible to do this using the Metadata API. This involved making a callout and using the user session to do so. In recent months Salesforce has started rejecting managed packages that do this during the security review process. Alternative methods using connected apps and OAuth are possible but using the Metadata API to alter security related metadata could still cause a failure.

There are cases where managed packages may want to offer a guided setup experience which may include creating Named Credentials. In some cases these credentials could be packaged. However in some cases the endpoint host will be subscriber specific so a dynamically created Named Credential will be a better choice. How can an Apex developer continue to offer this?

In the Winter ‘23 release it was possible to create and manipulate a new format Named Credential that used an existing External Credential but not create the External Credential using a pure Apex API exposed in the ConnectAPI namespace.

ConnectAPI.CredentialInput input = new ConnectAPI.CredentialInput();
input.authentication​Protocol = 'OAuth';
input.credentials = new Map<String, ConnectAPI.CredentialValueInput>();
input.externalCredential = 'MyExternalCredential';
input.principalName = 'MyPrincipal';
input.principalType = 'NamedPrincipal';
ConnectAPI.createCredential(input);

The developer name for the External Credential could be retrieved using getExternalCredentials to get a list of all credentials the user can authenticate to.

In Summer ‘23 it appears initially that the final parts of the puzzle are in place. We have the new createExternalCredential method to allow us to create a new external credential using data we gather from the user then create the Named Credential. So all is good!

But think back to the changes introduced in Summer ‘23. The link to the permission set is no longer part of the External Credential. It’s part of the permission set. So creating the External Credential and Named Credential is not enough: the permission set has to be updated. And there is no native Apex API for that. In fact it’s reasonable to assume that this new method is only being made available as it now does not allow Apex to alter the permissions of a user.

So in short you can automate the creation of a non-standard External Credential and Named Credential to automate setup for your users. But you cannot link it to a permission set so the Admin will still have to be prompted to take action

Read More