Skip to content

REST Client - Consumer

A REST API is referred to as a PROVIDER. The common used term for a REST CLIENT is a CONSUMER.

Runtime Architecture

MDRest4i MDRFRAME Consumer Runtime

Consumer Program

The Consumer program is the program generated by the SDK. It can be called directly or be embedded in any ILE program.

The general flow of a Consumer is:

  • Create a REST Client instance in memory via the MDRFRAME framework. This "handle" key ensures threadsafe data when calling MDRFRAME procedures during the execution of the Consumer program.
  • Set the request options: URL, logging, authorisation, PROXY, DCM, KDB etc see MDR_setClientOpt
  • Call or run your business logic, DB/IFS IO, and calls to IBM i applications/Stored procedures etc.
  • Build JSON, file, XML etc payloads.
  • Set request headers and query parameters.
  • Add attachments.
  • Make the request.
  • Handle the extraction of response headers and parsing payloads, or attachments
  • Call or run your business logic, DB/IFS IO, and calls to IBM i applications/Stored procedures etc.
  • Set any error messages
  • Release the "handle" created by MDRFRAME and therefore release resource allocation.
  • Return control to the calling program.

MDRFRAME takes care of all the socket communications, including SSL/TLS etc that occur when making the request, and receiving a response from the API/URI.

Examples

Info

In the COBOL example below the MDR-DATAGEN SECTION is used to generate JSON. This function is unique to MDRFRAME, and overcomes the limitation that IBM's DATA-GEN procedure is only available in RPGLE or from V7R2 upwards. The Copybook "MAPIC001C" below shows how the MDR_DATAGEN and MDR_DATAINTO functions use a special 'schema' to parse or generate JSON via the MDRFRAME framework. The MDR_DATAINTO-MDR_DATAGEN section has the details about how to use this.

**Free
// CRTBNDRPG PGM(&O/&ON) SRCFILE(&L/&F) OPTION(*EVENTF) DBGVIEW(*ALL) -
// USRPRF(*OWNER) TGTRLS(V7R2M0)

// RPGLE REST API Template Using DATA-GEN and DATA-INTO for JSON.
ctl-opt dftactgrp(*no) actgrp(*new);
ctl-opt BNDDIR('MDRFRAME');

/copy mdrframe

dcl-ds output qualified;
  message char(50); // example only : change as required
end-ds;

dcl-ds input qualified;
  message char(50); // example only : change as required
end-ds;

dcl-pi *n;
  handle    like(MDR_Handle_t);
  method    char(32) const;
  body      varchar(500000); // MAxSize: 16000000
end-pi;

dcl-s result varchar(1000);

// Logic to process request body
MDR_genParseOptions(handle: 'document_name=input');
data-into input %data('':'')
                %parser('MDRFRAME(PARSER)':handle);

eval-corr output = input;
// Logic to process response
MDR_genParseOptions(handle: 'document_name=output');
data-gen output %data(result: '')
                %gen('MDRFRAME(GENERATOR)':handle);

*Inlr = *On;
   PROCESS varchar
           apost
           nomonoprc
           nosync
           nostdtrunc

   IDENTIFICATION DIVISION.
   PROGRAM-ID.   CNS001.
   AUTHOR.       Midrange Dynamics.
  * Consumer program example with POST HTTP method.
  *>  CRTCBLMOD MODULE(&O/&ON) SRCFILE(&L/&F) DBGVIEW(&DV) -
  *>            OPTION(*SOURCE *EVENTF *IMBEDERR)
  *>  CRTPGM PGM(&O/&ON) MODULE(&O/&ON) BNDDIR(MDRFRAME) -
  *>         ACTGRP(*NEW)
  *****************************************************************
   ENVIRONMENT DIVISION.
   CONFIGURATION SECTION.
   SOURCE-COMPUTER. IBM-I.
   OBJECT-COMPUTER. IBM-I.

   SPECIAL-NAMES.
  * MDRest4i Special Names for iCore Procedures
  * Please insert any program specific SEPCIAL NAMES BEFORE this
  * COPYBOOK, and the COPYBOOK delimits the divsion with a period
   COPY MDRCBLSPC OF MCLBL.

  *****************************************************************
   DATA DIVISION.
  *****************************************************************
   WORKING-STORAGE SECTION.
  * MDRest4i REQ/RSP Payload Schemas
   COPY CNS001C OF   QLBLSRC.
  * MDRest4i Framework Variables
   COPY MDRCBLWSC OF MCLBL.
  * MDRest4i Large Framework Variables
  * Set sizes accoprding to maximum size required in this program
  * This will effect the size of the compiled object

  * MDR-DOC - by default this paramater is OMMITTED in the SECTIONs
  * MDR-DATAGEN and MDR-DATAINTO. For more information see comments
  * for MDR-DATAGEN
  * MAXSIZE: 16000000
  ******************************************************************
  * 01  MDR-DOC          PIC X(16773100).

  * MDR-PAYLOAD MAXSIZE: 16000000
  ******************************************************************
   01  MDR-PAYLOAD PIC X(10000).

  * MDR-CLIENT-CONFIG MAXSIZE: 32767
  ******************************************************************
   01  MDR-CLIENT-CONFIG PIC X(4096).

  * MDR-MESSAGE MAXSIZE: 32767
  ******************************************************************
   01  MDR-MESSAGE       PIC X(4096).

  * MDR-STRING MAXSIZE: 65536
  ******************************************************************
   01  MDR-STRING       PIC X(4096).

  * MDR-INPUT-BUFFER MAXSIZE: 5000000
  ******************************************************************
   01  MDR-INPUT-BUFFER      PIC X(10000).

  * MDR-JSON-STR MAXSIZE: 5242880
  ******************************************************************
   01  MDR-JSON-STR           PIC X(10000).

  * MDR-INPUT-STR MAXSIZE: 5242880
  ******************************************************************
   01  MDR-INPUT-STR          PIC X(10000).

  * MDR-OUTPUT-STR MAXSIZE: 5242880
  ******************************************************************
   01  MDR-OUTPUT-STR         PIC X(10000).

  * MDR-ERROR-MSG MAXSIZE: 32767
  ******************************************************************
   01  MDR-ERROR-MSG          PIC X(4096).

  * MDR-YLABEL MAXSIZE: 65535
  ******************************************************************
   01  MDR-YLABEL.
     49 MDR-YLABEL-LENGTH    PIC S9(4) USAGE BINARY VALUE 0.
     49 MDR-YLABEL-DATA      PIC X(1024).

  * MDR-YVALUE MAXSIZE: 65535
  ******************************************************************
   01  MDR-YVALUE.
     49 MDR-YVALUE-LENGTH    PIC S9(4) USAGE BINARY VALUE 0.
     49 MDR-YVALUE-DATA      PIC X(4096).

  * MDR-BUFSTR MAXSIZE: 2000000
  ******************************************************************
   01  MDR-BUFSTR            PIC X(4096).

  * MDR-SEND-DATA MAXSIZE: 16773100??? USE with MDR-REQUEST-YAJL
  ******************************************************************
   01  MDR-SEND-DATA         PIC X(4096).

  * MDR-RCV-DATA MAXSIZE: 16773100??? USE with MDR-REQUEST-YAJL
  ******************************************************************
   01  MDR-RCV-DATA          PIC X(4096).

  * ===============================================================
   LINKAGE SECTION.
   COPY MDRCBLLSC OF MCLBL.

   PROCEDURE DIVISION.
   0000-MAIN-CONTROL SECTION.

   BEG.
  * Create a new handle for a client connection and variables
       PERFORM MDR-NEWCLIENT
  * Defines Log File per consumer program into MDR-CLIENT-OPT-VALUE.
  * After that, Run the MDR-SETCLIENTOPT to write the API response.
  * See lognames.txt for naming format options.
       SET MDR-OPT-LOG-PATH TO TRUE.
       MOVE 'ifs:/mdrest4i/logs/cns001-%F.TXT' TO
       MDR-CLIENT-OPT-VALUE.

       PERFORM MDR-SETCLIENTOPT.

  * Below's Logic to create request body
       MOVE 1 TO MDR-NUM-STOCK OF MDR-A00001-REQ.
       MOVE 'Mountain' TO MDR-DEPARTMENT OF MDR-A00001-REQ(1).
       MOVE 'Bikes' TO MDR-MAINCATEGORY OF MDR-A00001-REQ(1).
       MOVE 'MTB' TO MDR-SUB_CATEGORY OF MDR-A00001-REQ(1).
       MOVE 1 TO MDR-NUM-SIZES OF MDR-A00001-REQ(1).
       MOVE 55 TO MDR-SIZES OF MDR-A00001-REQ(1, 1).
       MOVE 1 TO MDR-NUM-COLOURS OF MDR-A00001-REQ(1).
       MOVE 'Red' TO MDR-COLOURS OF MDR-A00001-REQ(1, 1).
  * Set the request schema into MDR-SCHEMA to process MDR-DATAGEN.
       MOVE MDR-A00001-REQ-SCHEMA TO MDR-SCHEMA

  * Set the MDR-PAYLOAD from request data structure.
       MOVE MDR-A00001-REQ TO MDR-PAYLOAD

  * Set the Data options for processing MDR-DATAGEN
       MOVE 'countprefix=num_ renameprefix=name_'
       TO MDR-DATA-OPTIONS

  * Generate JSON request to send JSON request.
       PERFORM MDR-DATAGEN.

  * Set HTTP-Method as required for this request handle.
       MOVE 'POST' TO MDR-METHOD

  * Set URI as required for this request handle
       MOVE 'http://dev.mdcms.ch:2580/mdrapi/API001' TO MDR-URL.

  * Make an HTTP request with an HTTP client. It will returns the
  * HTTP status code (200=success) or -1 if client-side error
  * occurred).
       PERFORM MDR-REQUEST.

  * If the HTTP status code is 200, parse the response using
  * MDR-DATAINTO.
       IF MDR-HTTP-CODE = 200
         INITIALIZE MDR-SCHEMA
         INITIALIZE MDR-PAYLOAD
         MOVE MDR-A00001-RSP-SCHEMA TO MDR-SCHEMA

         PERFORM MDR-DATAINTO

         MOVE MDR-PAYLOAD TO MDR-A00001-RSP
       ELSE
  * If fail, check error message using MDR-GETCLIENTERROR function.
  * It will return the error message into MDR-MESSAGE variable.
         PERFORM MDR-GETCLIENTERROR
       end-if.
  * Release handle for this request to clear memory
       PERFORM MDR-FREECLIENT.

       GOBACK.
  *  Default Procedures for MDRest4i Framework
   COPY MDRCBLPRC OF MCLBL.
*************************************************************************
*// Copybook generated by MDRest4i on 2023-08-11
* ***********************************************************************
*------------------------------------------------------------------------
* MDR-START-UUID : A00001
*------------------------------------------------------------------------
* Request Format UUID : A00001
  01  MDR-A00001-REQ-SCHEMA.
    10  MDR-A00001-REQ-LEN PIC 9(8) USAGE BINARY VALUE 470.
    10  MDR-A00001-REQ-001 PIC X(256) VALUE '{"toplevel":{"city":{"
-         '=type":"char","=len":50},"num_street-names":{"=type":"i
-         'nt","=len":10},"name_street_names":{"=type":"char","=le
-         'n":12,"=value":"street-names"},"street_names":{"=dim":9
-         ',"firststreet":{"=type":"char","=len":50},"secondstreet
-         '":{"=type":"ch'.
    10  MDR-A00001-REQ-002 PIC X(214) VALUE 'ar","=len":50}},"name_
-         'ajsonkey_withmuchlongernamethanwewoudlno":{"=type":"cha
-         'r","=len":40,"=value":"ajsonkey-withmuchlongernamethanw
-         'ewoudlno"},"ajsonkey_withmuchlongernamethanwewoudlno":{
-         '"=type":"char","=len":50}}}'.

* Response Format UUID : A00001
  01  MDR-A00001-RSP-SCHEMA.
    10  MDR-A00001-RSP-LEN PIC 9(8) USAGE BINARY VALUE 470.
    10  MDR-A00001-RSP-001 PIC X(256) VALUE '{"toplevel":{"city":{"
-         '=type":"char","=len":50},"num_street-names":{"=type":"i
-         'nt","=len":10},"name_street_names":{"=type":"char","=le
-         'n":12,"=value":"street-names"},"street_names":{"=dim":9
-         ',"firststreet":{"=type":"char","=len":50},"secondstreet
-         '":{"=type":"ch'.
    10  MDR-A00001-RSP-002 PIC X(214) VALUE 'ar","=len":50}},"name_
-         'ajsonkey_withmuchlongernamethanwewoudlno":{"=type":"cha
-         'r","=len":40,"=value":"ajsonkey-withmuchlongernamethanw
-         'ewoudlno"},"ajsonkey_withmuchlongernamethanwewoudlno":{
-         '"=type":"char","=len":50}}}'.

* Request Payload UUID : A00001
  01  MDR-A00001-REQ.
    05  MDR-TOPLEVEL.
      10  MDR-CITY PIC X(50).
      10  MDR-NUM-STREET-NAMES PIC S9(8) USAGE BINARY VALUE 0.
      10  MDR-NAME-STREET_NAMES PIC X(12) VALUE 'STREET-NAMES'.
      10  MDR-STREET_NAMES OCCURS 9.
        15  MDR-FIRSTSTREET PIC X(50).
        15  MDR-SECONDSTREET PIC X(50).
      10  MDR-NAME-AJSONKEY_WITHMUCHLONGERNAMETHANWEWOUDLNO
          PIC X(40) VALUE
          'AJSONKEY-WITHMUCHLONGERNAMETHANWEWOUDLNO'.
      10  MDR-AJSONKEY_WITHMUCHLONGERNAMETHANWEWOUDLNO PIC X(50).

* Response Payload UUID : A00001
   01  MDR-A00001-REQ.
     05  MDR-TOPLEVEL.
       10  MDR-CITY PIC X(50).
       10  MDR-NUM-STREET-NAMES PIC S9(8) USAGE BINARY VALUE 0.
       10  MDR-NAME-STREET_NAMES PIC X(12) VALUE 'STREET-NAMES'.
       10  MDR-STREET_NAMES OCCURS 9.
         15  MDR-FIRSTSTREET PIC X(50).
         15  MDR-SECONDSTREET PIC X(50).
       10  MDR-NAME-AJSONKEY_WITHMUCHLONGERNAMETHANWEWOUDLNO
           PIC X(40) VALUE
            'AJSONKEY-WITHMUCHLONGERNAMETHANWEWOUDLNO'.
       10  MDR-AJSONKEY_WITHMUCHLONGERNAMETHANWEWOUDLNO PIC X(50).

  * Response Payload UUID : A00001
   01  MDR-A00001-RSP.
     05  MDR-TOPLEVEL.
       10  MDR-CITY PIC X(50).
       10  MDR-NUM-STREET-NAMES PIC S9(8) USAGE BINARY VALUE 0.
       10  MDR-NAME-STREET_NAMES PIC X(12) VALUE 'STREET-NAMES'.
       10  MDR-STREET_NAMES OCCURS 9.
         15  MDR-FIRSTSTREET PIC X(50).
         15  MDR-SECONDSTREET PIC X(50).
       10  MDR-NAME-AJSONKEY_WITHMUCHLONGERNAMETHANWEWOUDLNO
           PIC X(40) VALUE
            'AJSONKEY-WITHMUCHLONGERNAMETHANWEWOUDLNO'.
       10  MDR-AJSONKEY_WITHMUCHLONGERNAMETHANWEWOUDLNO PIC X(50).