RESTJSON

This example program demonstrates the basic structure of an RPG program utilizing RPG-XML Suite to consume a REST based JSON web service via HTTP GET, and parse the JSON response.


     H DFTACTGRP(*NO) ACTGRP(*CALLER) BNDDIR('RXSBND')

      /copy QRPGLECPY,RXSCB                      RPG-XML Suite Prototypes & Definitions

     D JSONHandler     PR              N
     D  pType                         5I 0 Const
     D  pPath                              Const Like(RXS_Var64Kv_t)
     D  pIndex                       10U 0 Const
     D  pData                          *   Const
     D  pDataLen                     10U 0 Const

     D gTransmitDS     DS                  LikeDS(RXS_TransmitDS_t)
     D ParseJsonDS     DS                  LikeDS(RXS_ParseJsonDS_t)
     D ErrorDS         DS                  LikeDS(RXS_CatchThrowErrorDS_t)

     D Json            S                   Like(RXS_Var64Kv_t)

     D gNameList       S                   Like(RXS_Var64Kv_t)
     D gCount          S             10I 0

      /free

       // Please note that the REST web service being consumed by this example program
       //   is not 100% available due to metering being performed on the
       //   "demo" account. Usually you can make multiple attempts over time and
       //   get a proper response eventually.

       monitor;

         // Transmit

         RXS_ResetDS( gTransmitDS : RXS_DS_TYPE_TRANSMIT );
         gTransmitDS.URI = 'http://api.geonames.org/citiesJSON'
                         + '?north=44.1&south=-9.9&east=-22.4'
                         + '&west=55.2&lang=de&username=demo';
         gTransmitDS.LogFile = '/tmp/log.txt';
         gTransmitDS.HTTPMethod = RXS_HTTP_METHOD_GET;
         Json = RXS_Transmit( *Omit : gTransmitDS );

         // Parse

         gCount = 0;
         monitor;
           RXS_ResetDS( ParseJsonDS : RXS_DS_TYPE_PARSEJSON );
           ParseJsonDS.Handler = %Paddr( JSONHandler );
           RXS_ParseJson( Json : ParseJsonDS );
         on-error;
           RXS_DestroyJson( ParseJsonDS );
         endmon;

         // Output Parse Results as a Thrown Message

         RXS_ResetDS( ErrorDS : RXS_DS_TYPE_CATCHTHROWERROR );
         ErrorDS.MessageId = 'RXS9897';
         ErrorDS.MessageData = gNameList;
         ErrorDS.ThrowToCaller = RXS_YES;
         RXS_Throw( ErrorDS );


       on-error;

         RXS_Joblog('Unexpected error occurred. See previous messages.');

       endmon;

       *inlr = *on;

      /end-free

     P JSONHandler     B                   Export
     D                 PI              N
     D  pType                         5I 0 Const
     D  pPath                              Const Like(RXS_Var64Kv_t)
     D  pIndex                       10U 0 Const
     D  pData                          *   Const
     D  pDataLen                     10U 0 Const

      /free

       select;

         when pType = RXS_JSON_OBJECT_END
          and pPath = '/geonames[*]';
           gNameList += ', ';

         when pType = RXS_JSON_OBJECT_END
          and pPath = '/';
           if gCount > 0;
             gNameList += 'No more names!';
           endif;

         when pType = RXS_JSON_STRING
          and pPath = '/geonames[*]/toponymName';
           gCount += 1;
           gNameList += %char(gCount) + ': ';
           gNameList += %Str( pData : pDataLen );

         // If the service is unavailable to the usage metering mentioned earlier,
         //   there will be JSON data available for parsing per the below

         when pPath = '/status/message';
           gNameList = %Str( pData : pDataLen );

         when pPath = '/status/value';
           gNameList += ' (' + %Str( pData : pDataLen ) + ')';

       endsl;

       // If you want to stop parsing early for whatever reason, return
       // RXS_JSON_STOP_PARSING

       return RXS_JSON_CONTINUE_PARSING;

      /end-free

     P                 E