RPG Example reading JSON using YAJL from IFS 

 June 2, 2017

By  NickLitten

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

(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 :

JSNIFSYAJL Completed with 91 elements. Total runtime:11000 YAJL DECODE


Let’s look at some examples


IBM i Software Developer, Digital Dad, AS400 Anarchist, RPG Modernizer, Shameless Trekkie, Belligerent Nerd, Englishman Abroad and Passionate Eater of Cheese and Biscuits. Nick Litten Dot Com is a mixture of blog posts that can be sometimes serious, frequently playful and probably down-right pointless all in the space of a day. Enjoy your stay, feel free to comment and remember: If at first you don't succeed then skydiving probably isn't a hobby you should look into.

Nick Litten

related posts:

Swap Homes and Travel the World – Join Home Exchange
Surf the Web Securely with OPEN DNS
IBM i Software Change Management – CMS vs ALM – What’s in a Name?
Want to learn CL Programming?
{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}

Get In Touch

I’m always looking for awesome input, feedback and critique!


Snug CBD

 20% Discount

I have partnered with SNUG CBD givING you Organic CBD
20% discount code "NL20"