Call External Services Registered Actions from Apex

External Services—A Salesforce integration product that includes (1) registering an external web service that you submit as an OpenAPI-compliant specification defining the web service, and (2) magically (well, almost!) bringing the operations of your external web service into the Salesforce platform (see invocable actions) for use with point-and-click tools like Flow Builder. In a nutshell, it uses OpenAPI standards to connect external REST APIs declaratively.

Previously, actions created through External Services could only be invoked via Flow or Einstein Bots. But now with the Summer’22 release, we can directly access External Services registered actions from Apex to access reusable functionality when writing Apex code.

Let’s see how we can access external service action with Apex code.

First, register an External Services (example API hosted on Heroku: endpoint: https://th-external-services.herokuapp.com) in Salesforce org.

Step 1. Create a Named Credential

We need a simple way to secure our external web service and our Salesforce org in addition to a valid and supported schema. Named Credentials can be used to authenticate our callouts to the bank service endpoints for this task.

  • From Setup, enter Named Credentials in the Quick Find box, then select Named Credentials.
  • Click New Named Credential.
  • For Label, use Bank.
  • For Name, use Bank (in English).
  • For URL, use https://th-external-services.herokuapp.com
  • Leave other fields as they are and click Save.

Step 2. Register an External Service

  • From Setup, enter External Services in the Quick Find box, then select External Services.
  • Click New External Service.
  • For External Service Name, enter BankService (no space).
  • For Select, a Named Credential, select Bank (the Named Credential we just created).
  • Select Service Schema Relative URL, and enter /accounts/schema. This string is added to the Named Credential we just made. It’s the relative URL that points to the API spec. Together, they form the full URL from our service provider. For example https://th-external-services.herokuapp.com/accounts/schema.
  • Click Save & Next.
  • Select all of the Operations.
  • Click Next.
  • A list of External Service Actions appears. These actions are now available to you in Flow Builder. Use the scrollbar to view them all. The operations in your API spec have now become invocable actions in Salesforce!
  • Click Done.

The External Services have been successfully registered in the Salesforce org, and we can now use Apex code to perform the various operations (addAccount, getAccount, updateAccount, DeleteAccount) defined in the API.

In the past, we had to create an Apex HTTP class in order to make a call out to an API. In the example code below, we will call the addAccount endpoint to create a new account.

HTTPRequest hr = new HTTPRequest();
hr.setEndpoint('callout:Bank/accounts/DynamicsCorporation?accountType=Checking');
hr.setMethod('POST');
hr.setHeader('Accept', 'application/json');
hr.setHeader('Content-Type', 'text/plain');
hr.setTimeout(120000);
HTTP h = new http();
String responseBody = h.send(hr).getBody();
system.debug('response : '+ responseBody);
Map<String,Object> m = (Map<String,Object>) JSON.deserializeUntyped(responseBody);
for(String key: m.keySet()){
system.debug(key + '=>'+m.get(key));
}
view raw HTTPCallout.cls hosted with ❤ by GitHub

When you run this code, you will see the following log: it indicates that the account is created with id= 115, name = DynamicsCorporation, type = Checking, and avaialbleBalance = 0$

With the Summer22 release, we no longer need to write boilerplate code to make a callout to external services. The code examples below use the getAccount action to retrieve the Account that we just created with the above code snippet.

//Call external services registered actions from apex
//Instantiate the external service Apex class
ExternalService.BankService service = new ExternalService.BankService();
//set request
ExternalService.BankService.getAccount_Request req = new ExternalService.BankService.getAccount_Request();
req.accountName = 'DynamicsCorporation';
try{
//make callout
ExternalService.BankService.getAccount_Response res = service.getAccount(req);
system.debug('200 response id => '+ res.Code200.Id);
system.debug('200 repsonse: available balance => '+res.code200.availableBal);
}catch(ExternalService.BankService.getAccount_ResponseException exc){
system.debug('404 response: error message => '+ exc.code404.errorMessage);
}

getAccount_Request and getAccount_Response are automatically created when we register the external service.

In the preceding example, we saw a new way to call an external service to obtain the Account. Now, let’s try this method of calling an external service to invoke the addAccount action in order to create a new account.

ExternalService.BankService service = new ExternalService.BankService();
//set request
ExternalService.BankService.addAccount_Request req = new ExternalService.BankService.addAccount_Request();
req.accountName = 'GreenMotorCorporation';
req.accountType = 'Customer';
try{
//make callout
ExternalService.BankService.addAccount_Response res = service.addAccount(req);
system.debug('200 response id => '+ res.Code201.id);
system.debug('200 repsonse: name => '+res.Code201.name);
system.debug('200 repsonse: available balance => '+res.Code201.availableBal);
system.debug('200 repsonse: type => '+res.Code201.z0type);
}catch(ExternalService.BankService.getAccount_ResponseException exc){
system.debug('404 response: error message => '+ exc.code404.errorMessage);
}

Update Account action: In this example, the account type created in the previous example has been updated.

//update account
ExternalService.BankService service = new ExternalService.BankService();
//set request
ExternalService.BankService.updateAccount_Request req = new ExternalService.BankService.updateAccount_Request();
req.accountName ='GreenMotorCorporation';
req.accountType = 'Customer';
try{
//make callout
ExternalService.BankService.updateAccount_Response res = service.updateAccount(req);
system.debug('200 response id => '+ res.Code200.id);
system.debug('200 repsonse: name => '+res.Code200.name);
system.debug('200 repsonse: available balance => '+res.Code200.availableBal);
system.debug('200 repsonse: type => '+res.Code200.z0type);
}catch(ExternalService.BankService.getAccount_ResponseException exc){
system.debug('404 response: error message => '+ exc.code404.errorMessage);
}

Similarly, you can use an apex code to call the external service deleteAccount action.

Have fun coding! 🙂

References:

External Services

Salesforce Help: External Services

Salesforce Summer ’22 Release Notes

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s