Serve JSON Web Services using RPG and YAJL

If you are here asking yourself "How can an IBM-i software developer Serve JSON Web Services using IBM RPG and YAJL?" then you have come to the right place.

RPG: Handles business logic and database access natively on IBM i.
YAJL: Simplifies JSON generation without manual string building.
IBM i HTTP Server: Provides a robust platform to serve web requests.

Here’s a step-by-step guide for an IBM i software developer to serve JSON web services using RPG (Report Program Generator) and YAJL (Yet Another JSON Library). This approach leverages the IBM i platform’s capabilities and assumes familiarity with RPG programming and basic system configuration.

Steps to Serve JSON Web Services with RPG and YAJL on IBM i

1. Understand the Tools

RPG: Your primary programming language on IBM i. Modern RPG (RPG IV or free-format RPG) supports external procedure calls and dynamic data handling, making it suitable for web services.

YAJL: An open-source JSON parser and generator written in C, ported to IBM i by Scott Klement. It provides RPG-friendly interfaces to create and parse JSON efficiently. Download it from scottklement.com/yajl and install it on your system (instructions are included in the package).

2. Set Up Your IBM i Environment

Install YAJL: After downloading, compile and install the YAJL library into a library (e.g., YAJL) on your IBM i system. Ensure the library is in your library list when compiling RPG programs.

Configure the HTTP Server: Use the IBM HTTP Server (powered by Apache), which is pre-installed on IBM i. You’ll configure it to route web requests to your RPG program.

  •  Access the HTTP admin interface (typically at http://your-system:2001/HTTPAdmin).
  • Create or edit a configuration file (e.g., httpd.conf) to define a URL endpoint that triggers your RPG program.

3. Design Your Web Service

Decide what data to serve. For example, a stock quantity lookup service might accept an item number as input (e.g., /stockqty/ITEM123) and return JSON with the item’s quantity.

Plan your RESTful URL structure. REST is lightweight and ideal for this use case:

  • GET /stockqty → Returns all items.
  • GET /stockqty/ITEM123 → Returns data for a specific item.

4. Write the RPG Program

Here’s a simplified example of an RPG program using YAJL to generate JSON:

**free
ctl-opt dftactgrp(*no) actgrp(*new);

// Include YAJL prototypes (from Scott Klement's copybook)
dcl-pr yajl_beginObj extproc('yajl_gen_open');
end-pr;

dcl-pr yajl_endObj extproc('yajl_gen_close');
end-pr;

dcl-pr yajl_addChar extproc('yajl_gen_string');
value pointer value options(*string);
len int(10) value;
end-pr;

dcl-pr yajl_addNum extproc('yajl_gen_integer');
value int(20) value;
end-pr;

dcl-pr yajl_writeStdout extproc('yajl_gen_output');
end-pr;

// Variables
dcl-s itemNo char(10);
dcl-s qty int(10);

// Get input from HTTP request (simplified)
itemNo = %trim(getenv('QUERY_STRING')); // e.g., "ITEM123"

// Start JSON generation
yajl_beginObj();

// Add data to JSON
if itemNo <> *blanks;
 exec sql select qty into :qty from inventory where item = :itemNo;
 yajl_addChar('itemNo': %len(%trim(itemNo)));
 yajl_addChar(%trim(itemNo): %len(%trim(itemNo)));
 yajl_addChar('quantity': 8);
 yajl_addNum(qty);
else;
 // Example: Return all items (loop through table)
 exec sql declare c1 cursor for select item, qty from inventory;
 exec sql open c1;
 exec sql fetch c1 into :itemNo, :qty;
 dow sqlcod = 0;
  if sqlcod = 0;
   yajl_addChar('itemNo': 6);
   yajl_addChar(%trim(itemNo): %len(%trim(itemNo)));
   yajl_addChar('quantity': 8);
   yajl_addNum(qty);
  endif;
  exec sql fetch c1 into :itemNo, :qty;
 enddo;
 
 exec sql close c1;

endif;

yajl_endObj();

// Output JSON to HTTP response
yajl_writeStdout();

*inlr = *on;
return;

This is some quick and dirty pseudocode but it will give you the idea. It's key concepts are:

  •  Use getenv() to retrieve URL parameters (e.g., from QUERY_STRING).
  • Use SQL or native file operations to fetch data from your database.
  • YAJL functions like yajl_addChar and yajl_addNum build the JSON structure.

Ensure the Content-Type is set to application/json. Add this in your RPG program if needed:

dcl-s header char(100);
header = 'Content-Type: application/json' + x'0D25';
write(1: %addr(header): %len(%trim(header)));

5. Configure the HTTP Server

Edit your httpd.conf file to map a URL to your RPG program:

ScriptAlias /stockqty /QSYS.LIB/MYLIB.LIB/STOCKQTY.PGM
<Directory /QSYS.LIB/MYLIB.LIB>
Order Allow,Deny
Allow from all
</Directory>

Remember to Replace MYLIB with your library and STOCKQTY with your program name.

Once that's done, simply restart the HTTP server: STRTCPSVR SERVER(*HTTP) MYSERVER

6. Test Your Service

Access the service via a browser or tool like Postman:

http://your-system:port/stockqty/ITEM123

And if everything worked OK (and let's face it, you're are such a cool programmer its bound to right?) then you will get a result something like this:

{"itemNo": "ITEM123", "quantity": 50}

7. Enhance and Secure

Add error handling (e.g., invalid item numbers).

Implement authentication (e.g., basic auth via Apache or custom logic in RPG).

Use HTTPS by configuring SSL in the HTTP server for secure communication.

With this setup, you can create scalable, modern JSON web services while leveraging your existing RPG skills and IBM i infrastructure. Start small with a single endpoint, test thoroughly, and expand as needed!

{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}
>