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
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).