Sample Five: RESTDataSource

This sample provides code for working with the RESTDataSource object.

Sample RESTDataSource Script Contents

' SBM ModScript Example: RESTDataSource.tscm

/*
 ModScript Example: RESTDataSource.tscm
 -----------------------------------
 Use a RESTDataSource object. These can be created in Composer and bound to a URL, 
 or bound to an endpoint that can have a different URL per runtime environment. 
 This script will invoke the SBM JSON API "GetItemsByListingReport" function
 to get a list of items using a report.

 Requirement: 
 Deploy a RESTDataSource named "AE" pointing to the SBM AE server. Create a listing
 report in table "UBG_ISSUES" with a reference name "ModScript1" which takes 
 Active/Inactive as a query-at-runtime value.

 Logic: 
 Read a row from TS_RESTDATASOURCE, invoke it via Post with JSON post data, providing
 URL parameters and URL path parameters, parse the JSON into an object, process the 
 object and display items.
*/

var rest = Ext.CreateAppRecord( Ext.TableId( "TS_RESTDATASOURCE" ) );

/* 
 Assumes you have created a RESTDataSource called "AE" that points to the AE server.
 RESTDataSource objects can use Endpoints, which can help with deploying to test and 
 production systems.
*/
rest.Read( "AE" );

/* 
 Now, invoke the RESTDataSource to invoke the AE JSON API in order to read items using 
 a listing report. Here we assume you have a listing report with a reference name 
 "ModScript1" which takes Active/Inactive as a query-at-runtime value. We'll use Map and 
 Vector to build the JSON options we want to send to the JSONAPI; to_json() will convert
 our Maps, Vectors, Strings, etc to a well formatted JSON string. We will send the URL 
 parameters (values that come after the "?" in the URL) via a Vector of Pairs. We will 
 set up the URL path (the part of the URL that comes before the "?") using another 
 Vector; each value will be separated by a "/".
*/
var result = "";
if ( !rest.Post( result, 
    ["fixedFields":false, "fields":[["dbname":"TITLE"], ["dbname":"STATE"]]].to_json(), 
    [Pair("HasRuntimeParams",1), Pair("F_ACTIVEINACTIVE",0)], 
    ["jsonapi","GetItemsByListingReport","UBG_ISSUES","ModScript1"] ) ) {
  // write an error to Event Viewer
  Ext.LogErrorMsg("Rest call failed in script " + __FILE__ + ":\n" + 
    Shell.GetLastErrorMessage() );

  // write an error to Active Diagnostics
  ADLog.Message( __FILE__, __LINE__, ADLogLevelConstants.ERROR, "Rest call failed:\n" + 
    Shell.GetLastErrorMessage() );

  Shell.RedoMessage() = "Rest call failed";
  ExitScript();
}

// Parse the response, assuming we received JSON
var resultObj = from_json(result);

/*
 While debugging, writing the JSON out might help you understand what you are parsing.
 Convert back to json to get nice formatting (may be ignored by the browser):
 Ext.WriteStream(result.to_json() &&& "</br>"); 
*/

/* 
 Sometimes, you can get lost in your JSON object; do I have a map, a vector, or perhaps 
 a string or integer?  Printing out the data type of what "from_json" created might guide
 you in the code to write to process that object: 
 Ext.WriteStream( resultObj.get_type_info().name() );
*/

if ( resultObj.is_type(Map_type) && // we can check if we got a map object using this call. 
     resultObj.count("items")>0 && 
     resultObj["items"].is_type(Vector_type) ) {
  Ext.WriteStream( "<dl>" );
  for(entry : resultObj["items"]) {
    // ChaiScript supports in-string script processing using ${ codeGoesHere }
    Ext.WriteStream( "<dt>${entry["id"]["itemIdPrefixed"]}</dt>\n"); 
    for(value : entry["fields"]) {
      Ext.WriteStream("<dd>${value.first()}: ");
      if ( value.second().is_type(Map_type) &&
           value.second().count("value")>0 ) {
        Ext.WriteStream( value.second()["value"] );
      }
      Ext.WriteStream("</dd>\n");
    }
  }
} 

Ext.WriteStream( "</dl>" );