Skip to content

Consumer Path Tab

Screen Layout

The screen below appears when editing a Consumer spec and the "Path" tab is selected.

Each section controls a different aspect of OAPI/SWAGGER editing, and providing details for the RPG/COBOL generators.

Path Header - adding, deleting, selecting paths from the OAPI/SWAGGER specification.

HTTP Methods - Select or enable HTTP methods, and control what appears in the Method Options section such as parameters, response payload details etc.

Generation Options - Edit details that control the specifics of the generation of Consumer programs.

Method Options - Maintain details related to parameters, response body, request body, and tags for each path/method combination. Activated by selecting a button from the HTTP methods section.

Path Header

Select a path

The Paths configured in the OAPI/SWAGGER spec are displayed in the dropdown list on the left hand side.

Add a New Path

Click the button to add a New path.

Field Description
URI Path Mandatory path that will be used to call the remote API
Description Description of the path
Program Name Name of the program. / becomes the path if URI path is left blank
Gen Template This determines what generation pattern will be used. Possible values are:
RPGLE_EACH - One program per path method combination in RPGLE.
COBOL_DFT - One program per path method combination in COBOL ILE
Methods Select the methods by clicking the checkboxes
JWT Possible options: None, Yes and Remote

Click the button, and the path is added to the underlying OAPI/SWAGGER, and the dropdown list updated.

Delete a path

Click the button to delete the selected path.

Select "Yes" to delete the path.

Edit a path name

To change the pathname, click the pencil icon in the button bar. A popup window appears on click.

Make the necessary changes and press the Update button. This will update corresponding in the underlying OAPI/SWAGGER.

Adding Path Parameters

Path parameters can be added to the path name by enclosing the path parameter in curly braces as shown in the example below:

Click and the paths list gets updated as:

This will add an in: Path parameter to the requests section of the underlying OAPI/SWAGGER:

- in: path
  name: id
  description: id description
  required: true
  schema:
    type: string

This parameter will also appear in the HTTP Options when the parameters button is selected:

Path Parameters

This tells the generator to add function MDR_encode() in the consumer program, to add this parameter to the URI in the request:

// Path parameter variables.
dcl-s  pthparm2  varchar(10);
...
// Set the PATH parameters
MDR_encode(handle : encodeVar : %trimr(pthparm2));
uri += '/' + encodeVar;

Path Header Options

This section below the path editing line, includes more details for the selected path. These details correspond to the x-mdrGen object in the OAPI/SWAGGER section of the selected path.

Description A text description of the path. This description is used to as the text for the generated source member and object.
Gen Template Specifies which generation template is used to generate the code.
RPGLE_EACH - One program per path per HTTP method is generated.
Language Language the Consumer is generated in.
RPG - RPGLE
COBOL - COBOL - (available June 2024)
JWT Specifies if generator should add logic to add the Authorization header using MDRest4i JWT functions. (available June 2024)

HTTP Methods

Shows the lists of HTTP methods as different tabs

Enable a Method

To enable additional methods, select the method required and, if this method is not found in the OAPI/SAWGGER for this path, select the Enable xxxx Method button for that method: enable method button

This will add this method, with default values from the Consumer template for that method, to the OAPI/SWAGGER and update the screen, to show Generation Options for that method.


Generation Options for Consumer

These values are updated in the underlying OAPI/SWAGGER mdrGenOptions object of the selected method, inside for the x-mdrGen object for the selected path. They are used to determine what code is generated and where it is generated.

Note

MDRest4i supports iAsp, IFS and Source file options for compilation.

To allow for this a member APIPGM in source file QRPGLESRC in library APISRCLIB, must be entered using this IFS syntax:

/QSYS.LIB/APISRCLIB.LIB/QRPGLESRC.FILE/APIPGM.MBR

For those users not familiar with this syntax for lib/file/member or objects, a Helper popup has been created.

This popup allows the traditional manner of editing these details.

Generation Options for a Consumer

Generation Options Section

Summary

Short description of the API path.

Object Path

This is the IFS formatted path to the Library/object name of the consumer program. The library and object names can be edited using the popup.

Example: /QSYS.LIB/YOURLIB.LIB/APIPGM.PGM

Source Path

Location of source file/mbr for the Consumer program.

Example: /QSYS.LIB/STUART13.LIB/EXAMPLE.FILE/API002.MBR

Copybook Path

Location of copy book source file/mbr for payloads. The generator will create all payload data structures in this copybook, and add the /copy statement to the copybook in the generated Consumer.

Example: /QSYS.LIB/STUART13.LIB/EXAMPLE.FILE/API002.MBR

Authorization

Defines what type of authorization will be used in the request.

The generator adds variables and logic to add the Authorization header, to the request. The default value of string is created by the generator for these values. The developer should amend appropriately.

Selecting a value in the Authorization drop down, adds/sets the security object in the OAPI/SWAGGER for the path and method being edited in the paths tab.

Warning

In the generated consumer code, the value string is used by default. The appropriate values must be set by the developer.

Available options are:

Basic

When Basic is selected, the OAPI/SWAGGER is updated to:

OAPI/SWAGGER
/myapiname:
...
  get:
...
    security:
      - BasicAuth: []

The following logic is generated in the consumer program:

dcl-s authUser     varchar(256:4);
dcl-s authPwd      varchar(2048:4);
...
// TODO: Assign values for Basic authorization
authUser = 'string';
authPwd  = 'string';

// Set request Authorization header
opts = 'authtype=basic user=' + authUser + ' password=' + authPwd;
MDR_setClientCfg(handle:opts);

See MDR_setClientCfg for more information on setting these values.

Bearer

When Basic is selected, the OAPI/SWAGGER is updated to:

OAPI/SWAGGER
/myapiname:
...
  get:
...
    security:
      - BearerAuth: []

The following logic is generated in the consumer program:

// Variables used in Authorization process
dcl-s opts         varchar(32767:4);
dcl-s authToken      varchar(2048:4);
...
// Set the Bearer authorization by assigning the bearer token
// to the variable "authToken". e.g. authToken = 'Pnx9PH59vj0'
authToken = 'string'
opts = 'authtype=bearer authtoken=' +  authToken;
MDR_setClientCfg(handle:opts);

See MDR_setClientCfg for more information on setting these values.

OAPI securitySchemes

When a new consumer spec is created, these standard components.securitySchemes options are created from the consumer OAPI/SWAGGER template.

Only Basic and Bearer are currently supported.

components:
  securitySchemes:
    BasicAuth:
      type: http
      scheme: basic
    BearerAuth:
      type: http
      scheme: bearer

Setting this will also enable Authentication credentials to be entered in General tab, SWAGGGER UI section when testing. This is done by selecting the authorize button button.

Enter the appropriate values in the popup:

Available authorizations

These are then passed as the Authorization header with the request.

Description

Description of the selected method for that Consumer

Payload Format

This can be JSON, XML, or TXT. The generator will create logic to write or parse the correct payload syntax

Parse Method

Determines what parsing functions are used to process the inbound payload (response from api) in the generated code.

Available options are:

DATA-INTO - Uses the generated, qualified data structure (eg. mdlResp), assigned in the Responses section, IBM's DATA-GEN, and the MDRFRAME parser. It generates the following code:

// Process Response Data for HTTP Status 200
// Parse JSON response into ds "mdlresp" using DATA-INTO
MDR_genParseOptions(handle: 'document_name=mdlresp');
data-into mdlresp %data('': 'case=convert +
                        countprefix=num_ +
                        allowmissing=yes allowextra=yes')
                  %parser('MDRFRAME(PARSER)':handle);

JPATH Uses the generated, qualified data structure (eg. mdlResp), assigned in the Responses section, and generates MDRest4i JSON parsing functions such as MDR_jsonPathV etc in the consumer code. For example:

  dcl-s errorMsg   varchar(500:4);      // MaxSize: 4096
  dcl-s docnode    pointer;

  reset mdlresp;

  // Process Response Data for HTTP Status 200
  docnode = mdr_tree_parse(handle:*omit:*omit:errorMsg);
  if docnode <> *null;
  // Parse JSON response into ds "mdlresp" using JPathXX
    mdlresp.qrytitle = MDR_jsonPathV(handle:'qrytitle');
    mdlresp.qrysurname = MDR_jsonPathV(handle:'qrysurname');
    mdlresp.headersurname = MDR_jsonPathV(handle:'headersurname');
    mdlresp.cookie = MDR_jsonPathV(handle:'cookie');

  // Free memory resources used by YAJL parsing
  MDR_tree_free(handle:docNode);

IFS - No parsing occurs. Generates logic in the consumer program to write the inbound payload directly to the IFS. Add the IFS path to be used using the button. This will display a popup that allows the adding of path name to the IFS object to be used in the program.

button is provided next to the input box to use the File explorer to easily select or navigate to the desired path.

The File explorer opens when the button is clicked.

The following code is generated in the consumer program:

// Receive JSON response into an IFS
rcvstr = 'ifs:/home/stuart/consumer_response.json';
// Make an HTTP request. Return the HTTP status code (200=success)
// or -1 if there was a client-side error occurred.
code = MDR_request( handle
                  : method
                  : uri
                  : *omit
                  : rcvstr
                  );

Warning

rcvstr value is set with an "ifs:" prefix. Function MDR_request automatically writes the JSON response to this path as a result.

If the 'ifs:' prefix is not used, this function will not handle this automatic assignment.

See MDR_request for more details.

Gen Method

ONLY applicable to POST, PUT, PATCH HTTP methods. Determines how the outbound (consumer request) payload is handled in the generated code. Available options are:

DATA-GEN: Uses the generated, qualified data structure (eg. mdlReq), assigned in the Body section, and IBM's DATA-GEN and the MDRFRAME parser. It generates the following code:

// Create JSON request payload using DATA-GEN.
MDR_genParseOptions(handle: 'document_name=mdlReq');
data-gen mdlReq %data(result: 'doc=string +
                               countprefix=num_ +
                               renameprefix=name_')
                  %gen('MDRFRAME(GENERATOR)':handle);

MDR-YAJL: Generates MDRest4i YAJL functions such as mdr_addChar which use the generated, qualified data structure (eg. mdlReq - assigned in the Request Body) section to create JSON for the request body:

// Start writing the JSON using YAJL functions.
mdr_startJson(*OFF:*OFF);
// Build JSON request body using YAJL functions.
mdr_beginObject();
mdr_addChar('field1':mdlReq.field1);
mdr_addChar('field2':mdlReq.field2);
mdr_beginObject('object');
mdr_addChar('field3':mdlReq.object.field3);
mdr_addChar('field4':mdlReq.object.field4);
mdr_endObject();
mdr_endObject();

// Retrieve JSON loaded in buffer memory
mdr_getJson(*zero:JsonPtr:%size(JsonStr):rtnlen);

// End the JSON write
mdr_endJson();
// Assign the JSON into SendStr to send JSON request to the API
// using MDR_request.
If rtnlen > *zero;
  sendStr = %subst(JsonStr:1:rtnlen);
endif;

MDR-YAJL-NULL: Exactly the same mechanism as MDR-YAJL, but adds a parameter(isNull) to each function call *ON.

@param isNull (input) = if *ON output is null, otherwise is value supplied in second parameter

Example:

mdr_beginObject();
mdr_addChar('name':mdlReq.name:mdlReq.name=' ');
mdr_addNum('age':mdlReq.age:mdlReq.age=0);
mdr_endObject();

If mdlReq.name is blank, then the JSON will look like this: {"name": null}

if mdlReq.name is 'stuart', then the JSON will look like this: {"name": "stuart"}

Tip

For more details on writing JSON with this set of ILE functions in RPG or COBOL, see the MDRFRAME - JSON Functions sections of this guide.

IFS: Generates logic in the consumer program, to write the outbound payload, directly from the contents of an IFS file.

Add the IFS path to be used using the button. This will display a popup that allows the adding of path name to the IFS object to be used in the program.

button is provided next to the input box to use the File explorer to easily select or navigate to the desired path.

The File explorer opens when the button is clicked.

The following code is generated in the consumer program when IFS is used:

// Send JSON request from ifs
SendStr = 'ifs:/home/stuart/consumer_request.json';
// Make an HTTP request. Return the HTTP status code (200=success)
// or -1 if there was a client-side error occurred.
code = MDR_request( handle
                  : method
                  : uri
                  : sendstr
                  );

Warning

The sndstr value is set with an 'ifs:' prefix. Function MDR_request automatically writes the request payload from this path into the request.

If the 'ifs:' prefix is not used, this function will not handle this automatic assignment.

See MDR_request for more details.

Pgm Parms

This drop down allows selection of a schema. This schema will then be generated as a data structure which is then used as the entry parameters for the program.

Here are examples of the code generated in RPGLE and COBOL when these options are selected.

Example Schema:

Assigned to PGM Parms

Generated Code

**FREE                                                                                              
// Consumer program with entry param                                                                

ctl-opt dftactgrp(*no) actgrp(*new) option(*srcstmt)                                                
        bnddir('MDRFRAME');                                                                         

// Standard MDRest4i Copybooks                                                                      
/copy MDRUSRCPY                                                                                     
/copy MDRFRAME                                                                                      

// Main program PI definition.                                                                      
dcl-pi CNSEPARMS;                                                                                   
  PgmParam     likeds(Model1);                                                                      
end-pi;

// DS definitions for program call parameter                                                        
dcl-ds Model1 qualified;                                                                            
  name    varchar(15)     inz;                                                                      
  id      int(10)         inz;                                                                      
  address varchar(18)     inz;                                                                      
end-ds;
       LINKAGE SECTION.                                                                             
   COPY MDRCBLLSC OF QLBLSRC.                                                                   

   * Data Structure definition for call parameter                                                
     01  MDR-MODEL1.                                                                              
       03  MDR-NAME    PIC X(15).                                                                 
       03  MDR-ID      PIC S9(9) USAGE BINARY.                                                    
       03  MDR-ADDRESS PIC X(18).

Method Options

For the GET, DELETE and OPTIONS HTTP Methods, the following buttons appear:

HTTP methods POST, PUT, PATCH display the following buttons:

Option Description
Parameters Select to display and edit request parameters
Body Select to display and edit request body details.
(only for POST, PUT, PATCH method requests)
Responses Select to display and edit response body details.
Tags To create tags
Object Request For MDCMS users. This appears only if “Object Required" box is checked in the Edit Site

Parameters

Click on the button

To add a new parameter, click on the link

In the popup window, select the scope (query/header). Enter the parameter name and description and click button

Header parameters can be added using the same method.

The Parameters section is now updated:

Using function MDR_encode, the generator creates code that URL encodes the query parameter, then appends this encoded value to the uri variable. The uri variable is used to make the final request. In the above example, it also generates the function MDR_setHeader() to set the outbound HTTP header for the request:

// Set the HTTP header request parameters
MDR_setHeader(handle:'x-surname':x_surname);
// Set request URI
uri = 'https://host.com/myapiname';

// Set the URI parameters
if title <> *blanks;
  MDR_encode(handle : encodeVar : %trimr(title));
  uri += '?title=' + encodeVar;
endif;

Detailed Parameter Attributes

OAPI Schemas allow specifying of detailed attributes of variables. Using this mechanism, detailed attributes of the query, header and path variables can specified for the generated code.

Select a schema from the dropdown list of existing schemas.

On selecting the schema, the list of fields automatically is displayed in the next input field, Schema Field.

The OAPI/Swagger definition now adds the parameters field to the path and method selected, with references to the schema.

Here, the Swagger Extension fields x-schema, x-schemaFld are used.

Header Parameter Flow

In the case of header type parameters, an additional value flow can be specified.

The Swagger Extension x-flow field is used which can have the value "in", "out" or "both" depending on the boxes checked.

in requires the header value to be read by the consumer program, from the HTTP response.

out requires the header to be added by the consumer to the request.

both requires the header value to be sent with the request, AND read in the response. The following code uses function MDR_getHeader() to read the header from the response:

Body

Click on the button to edit the request body. The Body option/button is available only for POST, PUT and PATCH methods.

When this button is selected the Request Body section appears on the right hand side. Similar to the response section, it allows the request body schema and content-type to be selected.

When no request body has been added to the specification, the Request Body section looks like this:

Click on the button to create one.

Click the button.

Select the Content Type as application/json from the dropdown list.

Using the Schema drop down, select the schema that will be used for the outbound request body.

The Request Body section in the UI is updated, and the following object: requestBody is updated in the OAPI/Swagger.

Request Body Logic

In a consumer program, the schema in the body details above (object requestBody from the OAPI/SWAGGER), determines the payload definition. This schema is generated as a qualified data structure in RPG/COBOL.

For example here is a JSON sample from the schema used in body above:

{
  "field1": "something of value",
  "field2": "something of value2",
  "object": {
    "field3": "something of value3",
    "field4": "something of value4"
  }
}
The schema extracted from this sample by the SDK while creating a schema, is called mdlReq (or any other name you chose when creating the schema). Here is the schema tree diagram from the schema tab:

Below is the qualified data structure created from this by the SDK generator:

// Request payload definitions
dcl-ds mdlReq qualified;
  field1 varchar(18)     inz;
  field2 varchar(19)     inz;
  dcl-ds object;
    field3 varchar(19)     inz;
    field4 varchar(19)     inz;
  end-ds;
end-ds;

The logic used in the generated consumer program, to create the JSON request body payload, is determined by the Gen Method as described above.

Responses

By default, two HTTP responses are added to each consumer. Response 200 is the default status HTTP header value, consumer, that everything is OK.

HTTP Status 4xx is used to indicate a problem. This can be amended to whatever standard or value is desired. Here is a guideline that can be used to determine what codes are used in general:

https://developer.mozilla.org/en-US/docs/Web/HTTP/Status

Tip

The concept of REST is about collaborative development between often disparate development teams. Following industry norms wherever is a very good practice. This avoids unnecessary errors, when developers and users assume industry standards are being followed, especially where developers don't have direct communication, or API documentation is not of a high standard, or up to date.

Select the button.

From the Responses section on the right hand side, select the content type, and then select a schema created earlier from the Schema drop down (leaving model type as none).

The responses object in the underlying OAPI/SWAGGER is updated :

Response Body Logic

In a consumer program, the schema in the Responses details above (object responses from the OAPI/SWAGGER), determines the payload definition. This schema is generated as a qualified data structure in RPG/COBOL.

For example, the following JSON sample from the schema used in body above is:

{
  "qrytitle": "mr",
  "qrysurname": "smith",
  "headersurname": "header smith",
  "cookie": "bourbon biscuit"
}
The schema extracted from this sample by the SDK while creating a schema, is called mdResp (or any other name you chose when creating the schema). Here is the schema tree diagram from the schema tab:

Below is the qualified data structure created from this by the SDK generator:

// Response payload definitions
dcl-ds mdlresp qualified;
  qrytitle      varchar(15)     inz;
  qrysurname    varchar(30)     inz;
  headersurname varchar(30)     inz;
  cookie        varchar(30)     inz;
end-ds;

The logic used in the generated consumer program, to parse the JSON response body payload, is determined by the Parse Method as described above in the Generation Options section.

Helper buttons

MDRest4i supports iAsp, IFS and Source file options for compilation.

To allow for this a member APIPGM in source file QRPGLESRC in library APISRCLIB, must be entered using this IFS syntax:

/QSYS.LIB/APISRCLIB.LIB/QRPGLESRC.FILE/APIPGM.MBR

The same source file in the folder APISRC would use this syntax:

/APISRC/APIPGM.RPGLE

Using this format, an object path would look like this:

/QSYS.LIB/YOURLIB.LIB/APIPGM.PGM

For those users not familiar with this syntax for lib/file/member or objects, a Helper popup has been created.

This popup allows the traditional manner of editing these details.

Unless you are using a specific iASP, this value can be left blank for *SYSBAS iASP.

The previous form and underlying OAPI/SWAGGER are updated saved after the Done button is clicked.