Decode JSON webservice reply data (already stored in IFS) using YAJL
This reads the JSON from the IFS – decodes it using Y.A.J.L and reports on time taken to perform decode. Writing an RPG program to read JSON using YAJL is actually pretty straightforward — I hope this code example helps!
In this case the JSON data is a simple layout that looks like this:
{{ "users": [{ "userID": "@123", "firstName": "Billy", "lastName": "Bob", "initials": "123", "company": 110, "division": 30, "department": 325, "secProfile": "" }, { "userID": "AAATEMP", "firstName": "Albert", "lastName": "Smith", "initials": "AAA", "company": 110, "division": 1, "department": 1, "secProfile": "" }, { "userID": "AAATEST", "firstName": "Andy", "lastName": "Tester", "initials": "AAA", "company": 110, "division": 1, "department": 530, "secProfile": "AAT" }, { "userID": "AAA3", "firstName": "Fred", "lastName": "Blogs", "initials": "AA3", "company": 110, "division": 1, "department": 1, "secProfile": "AAA" }, { "userID": "AATEST", "firstName": "AA", "lastName": "TEST", "initials": "AAT", "company": 110, "division": 1, "department": 1, "secProfile": "" }, { "userID": "ABB", "firstName": "Abba", "lastName": "Dancing Queen", "initials": "", "company": 110, "division": 1, "department": 1, "secProfile": "" }, { "userID": "BINGBONG", "firstName": "Bing", "lastName": "Bong", "initials": "BB", "company": 110, "division": 2, "department": 2, "secProfile": "" }, { "userID": "LITTENN", "firstName": "Nick", "lastName": "Litten", "initials": "NJL", "company": 1, "division": 1, "department": 123, "secProfile": "Secret Squirrel" }]}
This JSON example contains the values:
USERID varchar(100); FIRSTNAME varchar(100); LASTNAME varchar(100); INITIALS varchar(100); COMPANY int(10); DIVISION int(10); DEPARTMENT int(10);
So. lets read it and break it out into fields, which I am just storing in an array. You could write them to a file just as easily…
**FREE /TITLE JSON_TABLE Decode JSON using Y.A.J.L. - Proof of Concept // ------------------------------------------------------ // PROGRAM CREATION OVERRIDES: // // Create as a Module and bind into ILE program // // JSNIFSYAJL.sqlrpgle (fully /free) // // This demonstrates reading JSON data from an IFS file and then // parsing that JSON to break out the subffields using Y.A.J.L. // Subfields within the objects are retrieved by their field names. // // The JSON data is loaded into a data structure suitable // for display from a program debugger. // // Compile - ADDLIBLE : LITTENN LMDTA06NL YAJL // // Check input data - // DSPLNK OBJ( ** value from IFSFilename ** ) // // MODIFICATION HISTORY: // // 07/17/2017 nick.litten V1.00 // ctl-opt dftactgrp(*no) actgrp('LITTENN') option(*nodebugio:*srcstmt:*nounref) bnddir('YAJL') alwnull(*inputonly) datfmt(*ISO) decedit('0.') copyright('| JSNIFSYAJL 1.0 06/27/2017 Use YAJL to read JSON from IFS and Parse.'); /include yajl_h // IFS file with JSON code that we will be reading and decoding dcl-c ifsFilename const('/littenn/getwebjsn.json'); dcl-ds jsonFields qualified template; USERID varchar(100); FIRSTNAME varchar(100); LASTNAME varchar(100); INITIALS varchar(100); COMPANY int(10); DIVISION int(10); DEPARTMENT int(10); end-ds; dcl-ds result qualified; success ind; errmsg varchar(500); jsonArray likeds(jsonFields) dim(9999); end-ds; dcl-s docNode like(yajl_val); dcl-s list like(yajl_val); dcl-s node like(yajl_val); dcl-s val like(yajl_val); dcl-s Count int(10); dcl-s lastElement int(10) inz; dcl-s errMsg varchar(500) inz(''); dcl-s strTimeStamp timestamp inz; // start of pgm dcl-s strJsonTimeStamp timestamp inz; // start of JSON decode logic dcl-s endTimeStamp timestamp inz; // used to calculate duration // Parms for logging-text being sent back into program message queue dcl-pr QMHSNDPM extpgm('QMHSNDPM'); *n char(7) const; // MsgID *n char(20) const; // MsgFile *n char(32767) const options(*varsize); // MsgData *n int(10) const; // MsgDtaLen *n char(10) const; // MsgType *n char(10) const; // StackEntry *n int(10) const; // StackCount *n char(4); // MsgKey *n char(32767) options(*varsize); // ErrorCode end-pr; dcl-ds ErrorCode; BytesProv int(10) inz(0); BytesAvail int(10) inz(0); end-ds; dcl-s joblogMsg char(200); dcl-s MsgKey char(4); /Title [---------- MAINLINE ---------- ] strTimeStamp=%timestamp(); // Load JSON in from the IFS file using YAJL docNode = yajl_stmf_load_tree( ifsFilename : errMsg ); // If it loaded then lets decode it: if errMsg = ''; strJsonTimeStamp=%timestamp(); // Write the JSON *header* level values node = YAJL_object_find(docNode: 'success'); result.success = YAJL_is_true(node); node = YAJL_object_find(docNode: 'errmsg'); result.errmsg = YAJL_get_string(node); list = YAJL_object_find(docNode: 'users'); // Write the JSON *data array* level values Count = 0; dow YAJL_ARRAY_LOOP( list: Count: node ); lastElement = Count; val = YAJL_object_find(node: 'userID'); result.jsonArray(Count).userID = yajl_get_string(val); val = YAJL_object_find(node: 'firstName'); result.jsonArray(Count).firstName = yajl_get_string(val); val = YAJL_object_find(node: 'lastName'); result.jsonArray(Count).lastName = yajl_get_string(val); val = YAJL_object_find(node: 'initials'); result.jsonArray(Count).initials = yajl_get_string(val); val = YAJL_object_find(node: 'company'); result.jsonArray(Count).company = yajl_get_number(val); val = YAJL_object_find(node: 'division'); result.jsonArray(Count).division = yajl_get_number(val); val = YAJL_object_find(node: 'department'); result.jsonArray(Count).department = yajl_get_number(val); enddo; yajl_tree_free(docNode); // Set Ending timestamps and calculate runtime endTimeStamp=%timestamp(); joblogMsg = 'JSNIFSYAJL Completed with ' + %char(lastElement) + ' elements. Total runtime:' + %char(%diff(endTimeStamp:strTimeStamp:*mseconds)) + ' YAJL DECODE only:' + %char(%diff(endTimeStamp:strJsonTimeStamp:*mseconds)) ; // stick that message into the joblog so we can clearly see the runtime QMHSNDPM( 'CPF9897' : 'QCPFMSG *LIBL' : joblogMsg : %len(%trimr(joblogMsg)) : '*DIAG' : '*' : 0 : MsgKey : ErrorCode ); else; // If unable to load JSON data from the IFS then tell the world result.success = *off; result.errmsg = 'Bugger! I couldnt read the IFS file'; endif; *inlr = *on;
So what does this do?
(1) reads the JSON from the input IFS File

20% Off with Coupon: NICKLITTEN
I highly recommend the SNUG CBD Tincture to help keep you in the zone when programming!
In Partnership with SNUG CBD - American readers get 20% off
(2) Stores a timestamp
(3) decodes the JSON and stores all the values in an array
(4) sends a message to the joblog saying how long it took.
In this case :
call JSNIFSYAJL JSNIFSYAJL Completed with 91 elements. Total runtime:11000 YAJL DECODE only:4000
#prettydarnquick