Each operation needs at least three lines of code using API Script RWU codeunit to run:
var
APIScriptRWU: Codeunit "API Script RWU";
ProviderID: Enum "Provider ID RWU";
OperationID: Enum "Operation ID RWU";
APIScriptRWU.INIT(OperationID::ProviderName_OperationName); //Set the identifier for saving Batch Entries
APIScriptRWU.ENDPOINT(ProviderID::ProviderName,OperationID::ProviderName_OperationName); //Select the provider and his operation
APIScriptRWU.EXECUTE(); //Start the operation
You can do a lot of things with RESTwithUS interface (like using variables or regular expressions, save data to Business Central etc.) – all these things are done during the EXECUTE
part of code.
But sometimes you may need to process the response with code to add more complex logic – for example, you can get the JSON values and save them to Business Central by yourself. And there are some handy functions for that in API Script RWU codeunit.
Tip: For more API Script functions see guideline API Script Functions Reference.
For testing purposes, you can call the provider and operation by their description. However, this is not recommended for production applications:
APIScriptRWU.INIT('OPERATION_BATCH_CODE');
APIScriptRWU.ENDPOINT('Provider Name','Operation Name');
There are some basic patterns, that you can use when processing the response with code.
Tip: For more details about error handling see guideline Debugging and Error Handling.
The EXECUTE function returns true, if the operation was processed successfuly (e.g. RESTwithUS received OK HTTP status from an external service or it was able to process the error response as success).
//Handle the response based on EXECUTE function result
if APIScriptRWU.EXECUTE() then
//Handle correct response
else
//Handle error response
You can use LAST_STATUS function to get the HTTP status code and handle specific statuses.
if APIScriptRWU.LAST_STATUS() = '408' then
//Handle the timeout HTTP status
The LAST_ERROR function returns an error message, if the operation ended with error.
if APIScriptRWU.LAST_ERROR() <> '' then
//Handle the error message
Let's have an example API response:
{
"result": [
{
"id": 1,
"no": "01121212",
"name": "Spotsmeyer's Furnishings",
"address": "612 South Sunset Drive",
"city": "Miami",
"countryCode": "US",
"phones": [
"123456789",
"999999999"
]
},
{
"id": 2,
"no": "01445544",
"name": "Progressive Home Furnishings",
"address": "3000 Roosevelt Blvd.",
"city": "Chicago",
"countryCode": "US",
"phones": []
}
]
}
If you ran the operation, the response data are saved in Batch Entries, but you can use a function to get a specific node data from the response:
NodeValue := APIScriptRWU.GET_RESPONSE_VALUE_BY_JPATH('JSONPath expression');
The JSONPath expression specifies filter for the node or nodes that you want to get – see some examples and basic description here.
But let's see at least a few basic examples:
Please note that in JSONPath syntax the array members are numbered from 0, so
$.result[0]
is first member ofresult
array,$.result[1]
second etc.
//Returns whole array in the result node in text format
NodeValue := APIScriptRWU.GET_RESPONSE_VALUE_BY_JPATH('$.result');
//Returns '1' - the id of the first customer
NodeValue := APIScriptRWU.GET_RESPONSE_VALUE_BY_JPATH('$.result[0].id');
//Returns '999999999' - the second phone of the first customer
NodeValue := APIScriptRWU.GET_RESPONSE_VALUE_BY_JPATH('$.result[0].phones[1]');
//Returns all id nodes in whole JSON - i.e. array [1,2]
NodeValue := APIScriptRWU.GET_RESPONSE_VALUE_BY_JPATH('$..id');
JSON Array can contain objects:
[
{"id":1,"name":"Johny Cash"},
{"id":2,"name":"Freddie Mercury"}
]
or simple (string, number, etc.) values:
[1,2,3]
["Monaco","France","USA"]
But in both cases the syntax is almost the same – just with object array, you need to work with child nodes too.
You can count members of JSON array using COUNT_RESPONSE_MEMBERS_BY_JPATH
function in API Script RWU codeunit. A few examples with the example API response:
//Returns '2' - Counts members in result array
Counter := APIScriptRWU.COUNT_RESPONSE_MEMBERS_BY_JPATH('$.result');
//Returns '2' - Counts members of phone array in the first result object
Counter := APIScriptRWU.COUNT_RESPONSE_MEMBERS_BY_JPATH('$.result[0].phones');
Function does not work with some advanced JSONPath expressions, for example, you are not able to count
id
nodes in the JSON with syntax$..id
.
Let's say you want to go through the example API response and work with id
and name
nodes. Then the code would look as follows:
//Count members in result array
Counter := APIScriptRWU.COUNT_RESPONSE_MEMBERS_BY_JPATH('$.result');
//Go through the array, which is numbered from 0
FOR i := 0 TO (Counter-1) DO BEGIN
//Get the current customer id and name
ID := APIScriptRWU.GET_RESPONSE_VALUE_BY_JPATH('$.result[' + FORMAT(i) + '].id');
Name := APIScriptRWU.GET_RESPONSE_VALUE_BY_JPATH('$.result[' + FORMAT(i) + '].name');
END;
Business Central has four standard objects for working with JSON data:
When processing API JSON response, you can use these objects and their functions together with RESTwithUS. Let's have an example JSON:
{
"result": [
{
"id": 1,
"no": "01121212",
"name": "Spotsmeyer's Furnishings",
"address": "612 South Sunset Drive",
"city": "Miami",
"countryCode": "US",
"phones": [
"123456789",
"999999999"
]
},
{
"id": 2,
"no": "01445544",
"name": "Progressive Home Furnishings",
"address": "3000 Roosevelt Blvd.",
"city": "Chicago",
"countryCode": "US",
"phones": []
}
]
}
First you will need some variables:
var
JSONData: JsonToken;
JArray: JsonArray;
JToken: JsonToken;
JObject: JsonObject;
APIScriptRWU: Codeunit "API Script RWU";
Then load the response JSON to main JsonToken variable and you can start processing it:
JSONData.ReadFrom(APIScriptRWU.GET_RESPONSE_JSON());
Get JSON node value by JSONPath expression (array numbers start from 0):
JSONData.SelectToken('$.result[0].no',JToken);
TextValue := JToken.AsValue().AsText(); //returns "01121212"
JSONData.SelectToken('$.result[1].id',JToken);
IntegerValue := JToken.AsValue().AsInteger(); //returns 2
Get array node and work with it:
JSONData.SelectToken('$.result[0].phones',JToken); //Get phones array of the first customer
JArray := JToken.AsArray();
ArrayCount := JArray.Count; //Count the array members
JArray.Get(0, JToken); //Get first phone number
PhoneNo := JToken.AsValue().AsText(); //Returns "123456789"
The function
SelectToken
does not work with some advanced JSONPath expressions, for example, you are not able to get allid
nodes in the JSON with syntax$..id
.
Get the single JSON object and work with it:
JSONData.SelectToken('$.result[0]',JToken); //Get first object from "result" array
JObject := JToken.AsObject();
HasPhonesNode := JObject.Contains('phones'); //Check, if the object has "phones" node
The last option is to work directly with Batch Entries saved by the operation. They are saved in API Entry RWU table which can be filtered by Batch Code, node Key etc.:
The advantage of this approach is that unlike processing JSON response directly with the functions mentioned earlier, in the Batch Entries you have processing information like variables or regular expression results (marked with yellow color).