Sample RPG Webservice - Get JBA Stockrooms (WEBGETSTR)

WEBGETSTR – get all stockrooms for a company code

Here is an example of an IBM i Webservice program. This one will serve up the the System/21 Stockroom master file (INP20) and returns a multi-occurrence data structure (array) of the stockrooms that the user is authorized to use.

It's written in SQL ILE RPG (SQLRPGLE) and easy to follow, even if you don't understand RPG language.

  • Control options define how the program is running
  • Uses SOAP activation group to help identify program
  • incoming XML will be converted to standard IBM i parameters by the IWS
  • Inputs – Company Code, User and Stockroom
  • Return values – Rtn is return value prefix for variable names
  • RtnMessage – return message to users

We are setting this webservice up for SOAP. This means it is limited to receiving the data in XML format.

NOTE: This exact same code could just as easily be setup as a REST webservice. This would expand the input parms to be able to accept JSON, and it would be invisible to the program because the conversion is all handled by the IWS (Integrated Web Server)

Let's look at the SQL RPGLE in more detail:


// -----------------------------------------------------------------
// Service Name - WEBGETSTR
// Function - This interface will be used to return all stockrooms for given company code
// -----------------------------------------------------------------
// WSDL - http://sysname:10010/web/services/WEBGETSTR?wsdl
// Author - Nick Litten
// This is a web service, called using the HTTP protocol
// and it accepts input data, processes it and returns results.
// -----------------------------------------------------------------
// Modification History:
// 2014-01-04 V1 Created
// 2014-01-12 V1.1 Added Department Code
// 2014-01-20 V1.2 Added Additional Return Codes
// -----------------------------------------------------------------

ctl-opt option(*srcstmt: *nodebugio)
  copyright('Version 1.2 January 20th 2014')

// Define Procedure and Interface parameters
// Return all stockrooms for given company code
dcl-s Company like(S21Stockroom.CONO20);
dcl-s User char(10);
dcl-s Stockroom char(2);
dcl-s RtnStatus char(1);
dcl-s RtnMessage char(256);
dcl-s RtnCount zoned(10);
dcl-s RtnList likeds(RtnArray) dim(999);

  *n like(Company) const;
  *n like(User) const;
  *n like(Stockroom) const;
  *n like(RtnStatus) options(*nopass);
  *n like(RtnMessage) options(*nopass);
  *n like(RtnCount) options(*nopass);
  *n like(RtnList) dim(999) options(*nopass);

// Use Data Structures to hold SQL file information for easy recognition
dcl-ds S21Stockroom extname('INP20') qualified end-ds;

// array to hold data reformatted ready for return
dcl-ds RtnArray qualified inz;
  RtnStockroom like(s21stockroom.strc20);
  RtnStockName like(s21stockroom.strn20);
  RtnDepartment like(s21stockroom.depc20);
  RtnAllowReceipts like(s21stockroom.rcta20);
  RtnAllowIssues like(s21stockroom.issa20);
  RtnAllowTransfers like(s21stockroom.trna20);
  RtnAllowSupplierOrders like(s21stockroom.spoa20);
  RtnAllowSalesOrders like(s21stockroom.slor20);
  RtnIncludeInStockValution like(s21stockroom.insv20);

dcl-ds LDA extname('LDA') dtaara(*lda) end-ds;

// Set SQL option, mainly to force cursor to close at endmodule
exec sql set option naming = *sys,
 commit = *none,
 usrprf = *user,
 dynusrprf = *user,
 datfmt = *iso,
 closqlcsr = *endmod ;

rtnCount = 0;
RtnMessage = *blanks;

// build conditions for this file access (note: do not qualify the file
// name with a library. It will be found from the library list defined to
// the webservice at http://<system>:2001/HTTPAdmin
exec SQL declare C1 cursor for
  select * from INP20
  where CONO20 = :Company
  for read only;

exec SQL open C1;

exec SQL fetch next from C1 into :S21Stockroom ;

dow sqlstt='00000' or %subst(sqlstt:1:2)='01';

  RtnCount += 1;
  RtnArray.RtnStockroom = S21Stockroom.STRC20;
  RtnArray.RtnStockName = S21Stockroom.STRN20;
  RtnArray.RtnDepartment = S21Stockroom.DEPC20;
  RtnArray.RtnAllowReceipts = S21Stockroom.RCTA20;
  RtnArray.RtnAllowIssues = S21Stockroom.ISSA20;
  RtnArray.RtnAllowTransfers = S21Stockroom.TRNA20;
  RtnArray.RtnAllowSupplierOrders = S21Stockroom.SPOA20;
  RtnArray.RtnAllowSalesOrders = S21Stockroom.SLOR20;
  RtnArray.RtnIncludeInStockValution = S21Stockroom.INSV20;
  RtnArray.RtnDepartment = S21Stockroom.DEPC20;

  // Store Datastructure values in next element of 'return array'
  RtnList(RtnCount) = RtnArray;

  // Read next record from Cursor selection
  exec SQL fetch next from C1 into :S21Stockroom ;


exec SQL close C1;

// Set Returncode to values requested by calling system ( in this case ACSIS)
if RtnCount < 1;
  RtnStatus = 'X';
  RtnMessage = 'Error! Company code ' + %trim(Company ) +
  ' has no stockrooms defined in System21! (File:INP20)';
  RtnStatus = 'Y';
  In LDA;
  RtnMessage = 'Print queue for user ' + %trim(L#USER) +
  ' is ' + %trim(L#PRQU) ;

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