Skip to content

REST API - Provider

The common used term for a REST API is a Provider. A REST Client is referred to as a Consumer.

Runtime Architecture

MDRest4i MDRFRAME API Runtime

The runtime architecture a REST API/Provider is self contained on the IBM i using native components.

An HTTP server is created using the MDRST/MDRHTTPAPI command. This server instance is configured to receive requests from a REST client and call the MDRAPI controller program.

The Provider program is the program generated by the SDK and is called by MDRAPI.

MDRAPI

MDRAPI is an ILE program. It is called as a CGi program by the HTTP server. Its roll is to control the flow of data between the HTTP server and the REST API program generated by the SDK.

MDRAPI allocates a unique "handle", gathers all the inbound message data from a request, and sets this up in memory using pointers keyed by the "handle" for each request.

It then calls the REST API program(written by the developer), passing some of the inbound data(handle, method, body) in the initial call. The REST API program, then manipulates the data in memory using calls to the MDRFRAME service program procedures, passing the "handle" passed in by MDRAPI each time.

The REST API program then passes control back to MDRAPI, and MDRAPI sends the response back to the REST Client request, via the HTTP server.

MDRAPI release any resource allocation created with the initial "handle".

What API Program to call, and what, and hwo to log each request is controlled by MDRAPI, as defined in the MDRDCFG database described in MDRST/MDRSTCFG section.

Info

It is imprtant therefore to either explicitly specify "mdrapi" in the uri to invoke a REST API in V14. In both cases an httpd.conf server directive must be set ensure MDRAPI is called. For example:

ScriptAliasMatch mdrapi /QSYS.LIB/MDRSTV14T.LIB/MDRAPI.PGM

ScriptAliasMatch ^/MDCMST86/AZURE/RELEASE/CALLBACK /QSYS.LIB/MDCMST86.LIB/MDRAPI.PGM

Provider Program

MDRAPI calls the provider program passing three parameters:

Parameter Description
handle unique threadsafe memory key used by MDRFRAME to allocate and deallocate memory structures
method the HTTP method of the request
body the HTTP message request body (if applicable)

The general flow of the provider program is:

  • Handle the extraction of inbound of REST headers, parameters, attachments, parsing payloads etc.
  • Call or run your business logic, DB/IFS IO, and calls to IBM i applications/Stored procedures etc.
  • Set any error messages.
  • Build REST headers and payloads.
  • Set the HTTP status.
  • Return control to MDRAPI which sends the response via the HTTP server to the REST Client.

This data extraction of the request, and writing of the response is executed by calling the appropriate MDRFRAME procedures (found in the MDRFRAME service program).

Examples

Below is an example of a simple REST Provider program that uses a POST method. The source of these examples can be found in MDRST/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.   MAPIC001.
AUTHOR.       Midrange Dynamics.

*>  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 MDRFRAME Procedures
* Please insert any program specific SEPCIAL NAMES BEFORE this
* COPYBOOK, and the COPYBOOK delimits the divsion with a period
COPY MDRCBLSPC OF QLBLSRC.

*****************************************************************
DATA DIVISION.
*****************************************************************
WORKING-STORAGE SECTION.
* MDRest4i REQ/RSP Payload Schemas
COPY MAPIC001C OF QLBLSRC.
* MDRest4i Framework Variables
COPY MDRCBLWSC OF QLBLSRC.
* MDRest4i Large Framework Variables
COPY MDRCBLWSVS OF QLBLSRC.

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

* MDR-HTTP-METHOD - To recive supplied HTTP method
******************************************************************
01  MDR-HTTP-METHOD      PIC X(10).

* MDR-INPUT-DATA - To recive input JSON request.
******************************************************************
01  MDR-INPUT-DATA.
    10 MDR-INPUT-DATA-LEN      PIC 9(9) USAGE BINARY.
    10 MDR-INPUT-DATA-BUFFER   PIC X(5000000).

* MDR-BODY-TYPE - To recive Body type ( *CAR or *VARCHAR)
******************************************************************
01  MDR-BODY-TYPE              PIC X(10).

PROCEDURE DIVISION USING MDR-HANDLE
                        MDR-HTTP-METHOD
                        MDR-INPUT-DATA
                        MDR-BODY-TYPE.

0000-MAIN-CONTROL SECTION.

BEG.

* Clear the MDR-SCHEMA and MDR-PAYLOAD before process the
* MDR-DATAGEN.
    INITIALIZE MDR-SCHEMA.
    INITIALIZE MDR-PAYLOAD.

* Logic to load response into response data structure.
    MOVE 1 TO MDR-NUM-STOCK OF MDR-A00001-RSP.
    MOVE 'MTB' TO MDR-DEPARTMENT OF MDR-A00001-RSP(1).
    MOVE 'Bikes' TO MDR-MAINCATEGORY OF MDR-A00001-RSP(1).
    MOVE 'MTB' TO MDR-SUB-CATEGORY OF MDR-A00001-RSP(1).
    MOVE 1 TO MDR-NUM-SIZES OF MDR-A00001-RSP(1).
    MOVE 55 TO MDR-SIZES OF MDR-A00001-RSP(1, 1).
    MOVE 1 TO MDR-NUM-COLOURS OF MDR-A00001-RSP(1).
    MOVE 'Red' TO MDR-COLOURS OF MDR-A00001-RSP(1, 1).

* Set the MDR_PAYLOAD from response data structure.
    MOVE MDR-A00001-RSP TO MDR-PAYLOAD.

* Set response Schema into MDR-SCHEMA.
    MOVE MDR-A00001-RSP-SCHEMA TO MDR-SCHEMA.

* Set Data options into MDR-DATA-OPTIONS.
    MOVE 'countprefix=num- renameprefix=name-'
    TO MDR-DATA-OPTIONS
* Generate JSON and send back to output response.
    PERFORM MDR-DATAGEN.

    GOBACK.
*  Default Procedures for MDRest4i Framework
COPY MDRCBLPRC OF QLBLSRC.
*************************************************************************
*// Copybook generated by MDRest4i on 2024-03-07
* ***********************************************************************
*------------------------------------------------------------------------
* MDR-START-UUID : A00001
*------------------------------------------------------------------------
* Response Format UUID : A00001
01  MDR-A00001-RSP-SCHEMA.
    10  MDR-A00001-RSP-LEN PIC 9(8) USAGE BINARY VALUE 720.
    10  MDR-A00001-RSP-001 PIC X(256) VALUE 'hex:7B226E756D2D53746F
-         '636B223A7B223D74797065223A22696E74222C223D6C656E223A313
-         '07D2C2253746F636B223A7B223D64696D223A392C22446570617274
-         '6D656E74223A7B223D74797065223A2263686172222C223D6C656E2
-         '23A337D2C2243617465676F7279223A7B224D61696E43617465676F
-         '7279223A7B223D'.
    10  MDR-A00001-RSP-002 PIC X(256) VALUE '74797065223A2263686172
-         '222C223D6C656E223A357D2C225375622D43617465676F7279223A7
-         'B223D74797065223A2263686172222C223D6C656E223A367D7D2C22
-         '6E756D2D53697A6573223A7B223D74797065223A22696E74222C223
-         'D6C656E223A31307D2C2253697A6573223A7B223D74797065223A22
-         '696E74222C223D'.
    10  MDR-A00001-RSP-003 PIC X(208) VALUE '6C656E223A31302C223D64
-         '696D223A397D2C226E756D2D436F6C6F757273223A7B223D7479706
-         '5223A22696E74222C223D6C656E223A31307D2C22436F6C6F757273
-         '223A7B223D74797065223A2263686172222C223D6C656E223A352C2
-         '23D64696D223A397D7D7D'.

* Response Payload UUID : A00001
* Created: 2024-03-07-11.34.39.125000
* Path: /MDRTST14/json/bikes_new.json
01  MDR-A00001-RSP.
    05  MDR-NUM-STOCK PIC S9(8) USAGE BINARY VALUE 0.
    05  MDR-STOCK OCCURS 9.
    10  MDR-DEPARTMENT PIC X(3).
    10  MDR-CATEGORY.
        15  MDR-MAINCATEGORY PIC X(5).
        15  MDR-SUB-CATEGORY PIC X(6).
    10  MDR-NUM-SIZES PIC S9(8) USAGE BINARY VALUE 0.
    10  MDR-SIZES PIC S9(9) USAGE BINARY OCCURS 9.
    10  MDR-NUM-COLOURS PIC S9(8) USAGE BINARY VALUE 0.
    10  MDR-COLOURS PIC X(5) OCCURS 9.