Step 3: Callout Template Request Body (JSON Format) (Old Interface)
Request Body Page (JSON Builder)
NOTE: If the template is using the GET method, this step is skipped. GET methods don’t use bodies.
NOTE: Once you start mapping fields in the JSON Builder, you CANNOT change the Main Object and Number of records on your Callout Template. If you want to change either of these, you need to remove all values set in the JSON Builder. Then you have the option to update the Main Object and Number or records. This is by design as the values set in JSON are dependent on the Main Object and Number of records selected.
About JSON
JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is also easy for machines to parse and generate.
JSON is built on two structures:
- A collection of name/value pairs.
- An ordered list of values.
An object is an unordered set of name/value pairs. An object begins with { (left brace) and ends with } (right brace). Each name is followed by : (colon) and the name/value pairs are separated by , (comma). A value can be a string in double quotes, or a number, or true or false or null, or an object or an array. Exmaple: { “name” : “Maria”, “age” : 30 }
An array is an ordered collection of values. An array begins with [ (left bracket) and ends with ] (right bracket). Values are separated by , (comma). Example: [ “orange”, “apple”, “cherry” ]
These structures can be nested. Example: { “name” : { “first” : “John”, “last” : “Doe” } , “email” : “john@example.com”, “children_age” : [ 12, 8, 3 ] }
More about JSON here: https://www.w3resource.com/JSON/introduction.php
JSON Builder
Let’s get started with the JSON Builder. To add nodes to the JSON body, select the ‘+’ icon as displayed below:
When adding a new node, first we need to set the Node Name, a name to define the value.
Then we have options to select either Object, List, Value, Array or Apex in the Node Type field. Here are a few more details to help you on your Node Type selection:
- Object: This will create a node in JSON, containing another structure of key-value pairs. You only need to provide the name of the node. After adding the Object node, you can add additional nodes inside this object by clicking the “+” button inside the newly created node.
- List: If this is selected, it will generate a list of objects in JSON. You will have the option to select a related list associated with your Main Object. You can even filter records by leveraging the Related List SOQL WHERE Clause (think the SOQL query in Data Loader). It is important to note that after creating the list, you will be able to map fields from the related list.
- Array: If you select this option, you can send a list of values in the node. It can be a list of static values or a field mapped from an object or a related list of objects, the latter generating a list with more than one entry. See “Selecting a Source” below for details.
- Value: Use this option to send single values in a node. It can be a static text, number, or a field mapped to the value of the node. See “Selecting a Source” below for details.
- Apex: This gives you the option to use an Apex class to generate this node. More details in the “Using Apex to generate a node” section below.
Selecting a Source
If you select “Array” or “Value” in the Node Type input, you are able to select a source for the value. That can be a Static value, a Salesforce Field or a Formula based on the fields of the main object.
- Static: This is a static option for if you want to send the same value every time the callout is made. Enter the value you want it to send here. If you choose “Array”, enter all the values that you want to send, one per line.
- Field: Here you can select any field from the Main Object or related objects you selected in the Callout Template. If you select a related list of objects and Node Type is Array, it will create a list with values from each related record.
- The Field Selector allows you to select fields from the Main Object, any related object (up to 5 levels deep) and any related list (one level). For example, if the Main Object is Account, the selection below allows you to select the Email of the Owner of each related Contact.
- If the selected field is a Blob field (for example Attachment -> Body or ContentVersion -> VersionData), then you will also be asked to provide the encoding to be used: Base64, Hex or Raw (which only works for UTF-8 content)
- Formula: This allows you to build a formula using the current object’s fields that will be used to generate the node. See more details in the “Using Formulas” section of this user guide.
- Custom Metadata: This allows you to map a field from a Custom Metadata Type record.
- Custom Setting: This allows you to map a field from a Hierarchy or List Custom Setting record.
Node Data Type
This lets you choose the data type of the JSON node value. It can be text, number or a true/false value.
Text values include out of the box fields like First Name, Last Name, Description and so on. Any field in Salesforce that is a data type of the following will need to be Text:
- Auto-Number
- Phone
- Text
- Text Area
- Text Area (Long)
- Text Area (Rich)
- Text Area (Encrypted)
- URL
When you are mapping Date or DateTime fields, you need to use Text as well. The Date fields are sent in the standard yyyy-MM-dd format and the DateTime fields are set in the standard yyyy-MM-ddTHH:mm:ss.sssZ format.
When Text is selected, you have the option to send empty strings when a value is null. If that option is selected, if the mapped value is null, then an empty string is sent instead.
Using Apex to generate a node
If the body of the callout is too complex to be generated with the methods above, you have the option to use an Apex class to generate part of the request body. Simply select “Apex” in node type and enter the class name that will generate that part of the JSON body. The class needs to be global and extend the d_wh.JSONNodeCallable abstract class.
Below is an example class that can be used to generate a JSON node.
global class TestCallable extends d_wh.JSONNodeCallable { global override Object Generate(List<Id> mainRecordIds, Object cachedData) { // Add code to generate json node } }
The mainRecordIds parameter contains the list of ids of the used record(s). If the callout is a “One Record” type, the list will contain one Id. If no Main Object is selected, the list will be empty.
The cachedData parameter contains the object returned by the CacheDataCallable class, and null if a cache class is not mentioned ( See details about CacheDataCallable below).
In order to generate a JSON body, the returned object can be one of the following types: String, Decimal, Boolean, List<Object>, Map<String, Object>. If list type or map type is returned, Object inside then should also be one of the types: String, Decimal, Boolean, List<Object>, Map<String, Object>.
If you select at least one node that is generated using Apex, you are provided with the option to run a cache class before generating nodes. In order to avoid hitting the SOQL limits when using apex to generate nodes (for example in lists), you can specify a class to run once, before the JSONNodeCallable classes. The class needs to be global and extend the d_wh.CacheDataCallable abstract class.
Below is an example class that can be used to cache some of the data before building the JSON.
global class TestCallable extends d_wh.CacheDataCallable { global override Object Cache(List<Id> mainRecordIds) { // Add code to query and return data to be cached } }
The mainRecordIds parameter contains the list of ids of the used record(s).
The response can be any type of object. It will be sent back to you as the cachedData parameter in the JSONNodeCallable class you use generating the node.
Create from sample JSON request
If you have a JSON Sample from the API documentation from the app or platform being implemented, you can create your Request Body quickly by utilizing the ‘Create from sample JSON request’ button. This enables you to quickly map your Main Object to your external system bypassing creating Node Names with stand-in values.
One example may be Quickbooks. Let’s say you are looking at the Account Request Body details on the API documentation of QuickBooks. You can find a Request Body sample to copy and pull into the Declarative Webhooks app:
After you copy the Request Body, select the ‘Create from sample JSON request’ button and paste your example.
Select “Generate” and you will see this has been added into the Request Body of your Callout Template. From here, you can begin mapping Salesforce fields from your Main Object by selecting the edit icon next to the row and replacing the static values from the sample body.
This helps you to quickly map without having to manually create each Node Name with a provided guide from your external system API documentation.
NOTE: If you have started mapping in the JSON Builder and you opt to utilize the ‘Create from sample JSON request’ button, your previous mapping will be overwritten. It is advised you begin with your sample JSON first before mapping additional Nodes.
Generate based on fields from Main Object
If you want to generate the JSON body based on fields from the main object, click the “Generate based on fields from Main Object” button.
It will open a popup that will allow you to select the fields used to generate the body.
Once you select all the fields, click “Generate” and see the JSON body being generated for you.
NOTE: If you have started mapping in the JSON Builder and you opt to utilize the ‘Generate based on fields from Main Object’ button, your previous request body will be overwritten.