Engagement Cloud - an Introduction to calling REST Services

July 24, 2018 | 6 minute read
Tim Bennett
CX Solution Architect
Text Size 100%:

Introduction

This article gives a brief introduction to calling REST services from Oracle Engagement Cloud. It assumes a basic understanding of Groovy, Application Composer, and the requirements of the REST services that you intend to call.

It sets out the basic steps required to setup and make a REST call and describes a couple of code patterns that that can be re-used. The REST services used in the examples come from Oracle Engagement Cloud, so there are no dependencies on other products or services.

 

High Level Process

The high-level steps to setup and call a REST service from Engagement Cloud are:

Define the Service
Set the resource path
Set the query parameters
Set the headers
Build the body
Call the operation
Parse the response
(Not all steps are required, depending on the use case).

 

Define the Service

REST services must be defined in App Composer before they can be used in Groovy scripts. Access the setup via Application Composer->Web Services:

                                

The service definition sets up the following:

Variable Name
The host being called
Static and dynamic URL path segments
Authentication Scheme
Methods
Sample payloads

 

Variable Name – give the service a meaningful variable name. This will be used to reference the service in Groovy.

When entering the URL, consider re-use and whether or not dynamic path segments can be used. Dynamic segments are defined using the notation ##<path_segment>##

Example URL

Consider the URL for Account Notes in Oracle Engagement Cloud:

https://<myHost>/crmRestApi/resources/latest/accounts/<PartyNumber>/child/Note

 

The only dynamic part of this appears to be the Party Number, so the URL could be entered as:

https://<myHost>/crmRestApi/resources/latest/accounts/##PartyNumber##/child/Note

 

However, look at the URL for Opportunity Notes:

https://<myHost>/crmRestApi/resources/latest/opportunities/<OpptyNumber>/child/Note

 

It is the same pattern as Account Notes, simply with a different object and a different object Id.

Therefore, the URL could be defined as:

https://<myHost>/crmRestApi/resources/latest/##object##/##key##/child/Note

 

Depending on the service, further path segments may be dynamic. For example, looking at the other child entities of Opportunity and Account (and many other objects in Engagement Cloud), it can be seen that they share the same pattern:

https://<myHost>/crmRestApi/resources/latest/##object##/##key##/child/##childName##

 

The above URL pattern will give access to almost every child of every object in Oracle Engagement Cloud. Do the same with any REST service that is used – identify the static parts of the path segments and those that can be provided at runtime.

Security – select the appropriate Authentication scheme for the service.

Select the Methods to be called and provide sample payloads for the methods that will be used. The sample payloads are used to provide design time hints in the expression builder, but a simple {} works too.

Note, once the service has been defined, the URL cannot be changed!

Example Service Definition:

                          

 

The example above is used in the following groovy examples.

 

Use in Groovy

Having defined the service, it can be used wherever Groovy scripts can be used. Just because a REST service can be called from anywhere does not necessarily mean it is a good idea! For example, a formula field that derives its value from a REST call can be created, and that formula field can be added to a list.  REST calls made from within object events, field events, and formula fields will wait for a response so could impact the user experience. If the result of a call is not required immediately, consider using asynchronous calls by using Object Workflows.

Once the REST service has been registered, it will become available for selection from the Groovy editor:

                       

Note the first 3 parameters above – they are the dynamic path segments that were defined earlier using ##<path_segment>## in the URL definition.

When calling the service from Groovy, there are 7 things that may need to be done:

1. assign the service to a variable
2. provide the path parameters
3. build and apply the query parameters
4. build and apply headers
5. provide a body
6. call the service
7. process the response

These steps are illustrated in a couple of contrived examples below. Both use Groovy to call Engagement Cloud Services that reside in the same instance, hence the use of "Propagate user identity using SAML".

GET

This example retrieves the Sales Account Team for an Account, parses the Sales Team Members from the result and saves them to a custom field. The numbers in the comments refer to the steps outlined above.

println("getSalesTeam") 
// 1. assign the service to a variable 
// this is optional, but makes it much easier to read your code 
def childService = adf.webServices.salesCloudChild 
// 2. set the path segments, these are usually required 
// if you do not set a segment you can end up calling services that have a URL like http://myService/path1//path 
def objectName = 'accounts'
def objectID = PartyNumber           //assumes this code is being run in the context of an Account record 
def childName = 'SalesTeamMember' 
// 3. build the query parameters map. The pattern below is one of several ways you can build a map 
def queryParms = [:] 
queryParms.fields='ResourceName,ResourceOrgName' 
queryParms.onlyData='true' 
// apply the query parameters to the service 
childService.dynamicQueryParams = queryParms 
// 6. call the service and assign the result to response 
def response = childService.GET(objectName, objectID, childName) 
def msg = "" 
// 7. process the response - see section later for more information on this 
for (item in response.items) { 
	msg += "${item.ResourceName}, ${item.ResourceOrgName} 
" 
	} 
// Note if you want to try this example yourself, you will need to add a custom Long Text field called SalesTeam. 
setAttribute("SalesTeam_c", msg)

 

POST

This example creates an Account Note using the same service definition as the example above.

println("Create Note") 
// 1. assign the service 
def childService = adf.webServices.salesCloudChild 
// 2. set the path segments. 
def objectName='opportunities' 
def objectID = OptyNumber              //assumes this code is being run in the context of an Opportunity record 
def childName = 'Note' 
// 4. build an HTTP headers map. 
def headers = [:] 
headers.'Content-Type' = 'application/vnd.oracle.adf.resourceitem+json' 
// apply the headers 
childService.requestHTTPHeaders=headers 
// 5. build the body/payload // This will build a map equivalent to the json payload {"NoteTypeCode": "GENERAL","NoteTxt": "SGVsbG8gV29ybGQ="} 
def body = [:] 
body.NoteTypeCode = 'GENERAL' 
body.NoteTxt = encodeToBase64('Hello World') 
// 6. call the service. Surround with try/catch if you want to handle errors 
try {
       def response = childService.POST(objectName, objectID, childName, body) 
    } catch(Exception e) {
       println("Response Headers: ${childService.responseHTTPHeaders}")
       println("Status:  ${childService.statusCode}")
       println("Error: ${e}") 
    } 

 

Processing Responses

In the GET example above, the response from the service was saved to a variable called response. This section gives a brief overview on how to process this. Note - this assumes that the response is of a known fixed format. Other techniques are needed to process unknown structures, but these are beyond the scope of this article.

The first thing to do is call the service from whatever testing tool you prefer - cURL, Postman, SoapUI, etc. take your pick.

A call to the service used in the GET example gives the following response:

{
  "items": [
    {
      "ResourceOrgName": "Product Development",
      "ResourceName": "Fred Jones"
    },
    {
      "ResourceOrgName": "Regional Specialists",
      "ResourceName": "Tim Bennett"
    },
    {
      "ResourceOrgName": "Product Development",
      "ResourceName": "Terry Turner"
    }
  ],
  "count": 3,
  "hasMore": false,
  "limit": 25,
  "offset": 0,
  "links": [
    {
      "rel": "self",
      "href": "https://myService.com/crmRestApi/resources/11.13.18.02/accounts/5/child/SalesTeamMember",
      "name": "SalesTeamMember",
      "kind": "collection"
    }
  ]
}

 

Looking at this response, note it contains an array of items, so the groovy code can access this using response.items 

The line for (item in response.items) loops through the response.items array and assigns each entry to a variable called item. So the first pass through the loop will set item to:

{   "ResourceOrgName" : "Product Development",   "ResourceName" : "Fred Jones" }

 

Entries within item can now be accessed using item.<key>, Hence the code:

for (item in response.items) {       
     msg += "${item.ResourceName}, ${item.ResourceOrgName} 
" 
}

 

Conclusion

The above code patterns can be used as templates for many REST calls from Oracle Engagement Cloud. Even though the examples show calls to the same instance of Engagement Cloud, the steps required to call external services are the same.

 

Tim Bennett

CX Solution Architect

Solution Architect specialising in Oracle Sales Cloud configuration and integration, particularly security and scripting.


Previous Post

A production pattern for frequent updates with PGX

Michael J. Sullivan | 3 min read

Next Post


Custom Login Widget for Oracle Identity Cloud Services

Andre Correa Neto | 7 min read