Creating and Editing SWAGGER Specifications
OpenAPI 3.0 Specification
SWAGGER (now know as Open API Specification or sometimes abbreviated as OAS3 or OAPI), allows you to describe the structure of your APIs so that machines and humans can read them.
The ability of APIs to describe their own structure is the root of all awesomeness in Swagger. Why is it so great? Well, by reading your API’s structure, you can automatically build beautiful and interactive API documentation with SWAGGER UI. Accelerator can also automatically generate client/server libraries/programs for your API in many languages (now including RPGLE using rest4i), and explore other possibilities like automated testing.
API specifications can be written in YAML or JSON. The format is easy to learn and readable to both humans and machines. The complete OpenAPI Specification can be found on GitHub: OpenAPI 3.0 Specification
MDRest4i uses the SWAGGER definition passed as a request body to the MDRSDK api on the IBM i, to generate RPGLE and COBOL code for Consumers and Providers.
SWAGGER extensions
SWAGGER extensions (JSON objects prefixed with an “x-”) are added to each SWAGGER specification to facilitate some of the code generation processes. Subfields inside an x- extension need not have the x- prefix
These are listed below, with the swagger key or path(path as in JSON or YAML path not REST API path) they are extending. For example x-mdrinfo appears in the "/info" of the swagger document, where "/" is the root
x-mdrinfo
Extends: /info Old Name: x-mdrinfo Function: This contains information about swagger spec as published in MDRest4i Documenter. Example:
x-mdrinfo:
environment: RestTest
refuuid: testSQLStu
description: Documentation on MD Documenter
publishDate: '2023-05-09T14:14:58.051Z'
url: /docu/?envrefuuid=RestTest&refuuid=testSQLStu
x-forceOverwrite: false
x-mdrGenRequest
Extends: root Old Name: n/a Function: Created by SDK when submitting a generation request. Specifies the selections made by the user when requesting code generation. Example:
x-mdrGenRequest:
genPath: '/myapiname'
genMethod:
- POST
- GET
genRequestDate: '2023-06-26T15:11:08.658Z'
x-mdrGen
Extends: /path - Old Name: x-mdrinfo Function: This is found at the root of each /path in the SWAGGER spec
paths:
/myapiname{pathparm2}:
x-mdrGen:
# Extension of path
RESTtype: consumer
# Tells the generator what program type to create. consumer or API
genTemplate: RPGLE_EACH
# Tells the generator which template to use in the generator config/template file. RPGLE_EACH = one program per method, RPGLE_ALL = all methods in one program(This will be written after v14.0). The details of these are stored in mdrsdk_Templates.json
language: RPGLE
jwt: 'N'
# GEN logic to get Authorization header
mdrGenOptions:
# Tells generator the details for each method
GET:
# The same structure below is used for GET, DELETE, and OPTIONS methods
object: '/QSYS.LIB/SKDEMO14.LIB/SKDEMO14.PGM'
# Library/object name of the API or consumer program
source: '/QSYS.LIB/SKDEMO14.LIB/QDEMOSRC.FILE/SKDEMO14.MBR'
# location of source file/mbr for the API or consumer. uses either IFS format /mdrtst14/src/skdemo.rpgle .LIB format
copybookPath: '/QSYS.LIB/SKDEMO14.LIB/QDEMOSRC.FILE/SKDEMO14P.MBR'
# location of copy book source file/mbr for payloads. uses either IFS format /mdrtst14/src/skdemo.rpgle .LIB format
lastmdrGen: '1970-01-01T00:00:00.000Z'
# time stamp for last time program was generated. Updated with return from MDRSDK. When OAPI spec if first created this value is set to zero : 1970-01-01T00:00:00.000Z
msgLvl: 10 # NOTEMP
# message level from generator API. Updated with return from MDRSDK. Not added until a generation attempt is made and response form MDRSDK received
msg: SUCCESS - source generated and object compiled # NOTEMP
# message text from generator API. Updated with return from MDRSDK. Not added until a generation attempt is made and response form MDRSDK received
url: https://dev.mdcms.ch/mdrdemod12/helloworld # CONSUMER ONLY
# Used by generator to determine endpoint/schema of request.
authorization: Basic # CONSUMER ONLY: can be "Basic", "Bearer" or "Digest"
DCMApp: MDREST4I_CLIENT # NOTEMP # CONSUMER ONLY
# Which DCM Application to use in connection. Takes precedence over keystore, but if not specified, a default keystore (see below) is used.
APPID: MDR001 # NOTEMP # CONSUMER ONLY
# Which APPid detail to use from MDRCREDX credentials store
CLIENTID: AWS001 # NOTEMP # CONSUMER ONLY
# Which CLIENTID detail to use from MDRCREDX credentials store
keystore: # NOTEMP # CONSUMER ONLY
path: '/QIBM/USERDATA/ICSS/CERT/SERVER/DEFAULT.KDB'
# IFS path to keystore file. Default = *SYSTEM
label: 'sk-ecdsa-2048-key'
# label within keystore (default = none)
password: 'fr0gzEatFl!es'
# password needed to access keystore (default = none)
payloads:
# This object will describe how payloads will be parsed and generated and what format XML/JSON etc will be used
format: JSON
# This can be JSON and XML and TXT for now
parseMethod: DATA-INTO
# This will control what happens to in bound payloads. initially we will allow DATA-INTO, JPATH, IFS.
parseInto: '/mdrest4i/data/input.json'
# This value is used by the generator to determine where the payload coming in to in the request(Provider) and response(Consumer) will be written to.
#For example If parseMethod = IFS, the generator will always use a generated variable 'parsePath' to set the path where the payload is written. If it has a value, then the generator will create the variable and then assign this value in the generated code. If parsePath is blank, the generator will assign a default value to the generated parsePath variable such as '/mdrest4i/payloads/{pgmname}/input.json'.
# If parseMethod = DATA-INTO for example the SDK user can specify where the payload should end up and in what format
parseIntoFormat: UTF-8
# Tells the generator how to generate code to handle the format of the parseInto requirement.
paging: false # NOTEMP
# GEN logic to send and receive pagination headers
missingEntryHandling: false # NOTEMP
# GEN logic to for handling missing entries in request body
numExceptionBypass: true # NOTEMP
# GEN logic for exception handling of numbers from request body, too large for numeric variables
callType: MODULE # NOTEMP PROVIDER ONLY
# API ONLY: GEN logic for calling a module from API. enum: MODULE, PGM, SRVPGM.
called: # NOTEMP PROVIDER ONLY
# Calling details used by generator - only exists in swagger if added in UI by user.
callLib: STUART
# qualified library name for module. *LIBL can be used so no qualified name is used in generated code
callname: MYMOD
# module, service program or program name
procName: GETSTUFF
# procedure name
callparms:
# GEN logic for parameters to be passed to called
inqry:
# parameters from query string used in call
- accountid
inhdr:
# parameters from HTTP headers used in call
- x-name
inpth:
- pathparm2
# parameters from API path used in call
POST:
# The same structure below is used for POST, PATCH and PUT methods
object: '/QSYS.LIB/SKDEMO14.LIB/SKDEMO14.PGM'
# Library/object name of the API or consumer program
source: '/QSYS.LIB/SKDEMO14.LIB/QDEMOSRC.FILE/SKDEMO14.MBR'
# location of source file/mbr for the API or consumer. uses either IFS format /mdrtst14/src/skdemo.rpgle .LIB format
copybookPath: '/QSYS.LIB/SKDEMO14.LIB/QDEMOSRC.FILE/SKDEMO14P.MBR'
# location of copy book source file/mbr for payloads. uses either IFS format /mdrtst14/src/skdemo.rpgle .LIB format
lastmdrGen: '1970-01-01T00:00:00.000Z'
# time stamp for last time program was generated. Updated with return from MDRSDK. When OAPI spec if first created this value is set to zero : 1970-01-01T00:00:00.000Z
msgLvl: 10 # NOTEMP
# message level from generator API. Updated with return from MDRSDK. Not added until a generation attempt is made and response form MDRSDK received
msg: SUCCESS - source generated and object compiled # NOTEMP
# message text from generator API. Updated with return from MDRSDK. Not added until a generation attempt is made and response form MDRSDK received
url: https://dev.mdcms.ch/mdrdemod12/helloworld
# CONSUMER ONLY: Used by generator to determine endpoint/schema of request.
authorization: Basic # CONSUMER ONLY: can be "Basic", "Bearer" or "Digest". Adds the relevant logic to consumer for setting the authorization details before the request is made # NOTEMP
DCMApp: MDREST4I_CLIENT # CONSUMER ONLY # NOTEMP
# Which DCM Application to use in connection
APPID: MDR001 # CONSUMER ONLY # NOTEMP
# Which APPid detail to use from MDRCREDX credentials store
CLIENTID: AWS001 # CONSUMER ONLY # NOTEMP
# Which CLIENTID detail to use from MDRCREDX credentials store
payloads:
# This object will describe how payloads will be parsed and generated and what format XML/JSON etc will be used
format: JSON
# This can be JSON and XML and TXT for now
parseMethod: DATA-INTO
# This will control what happens to inbound payloads. initially we will allow DATA-INTO, JPATH(used for mdr_JSONPATHV etc), IFS. MDR-DATAINTO(used for MDR-DATAINTO), will be in V14.2
parseInto: '/mdrest4i/data/input.json'
# This value is used by the generator to determine where the payload coming in to in the request(Provider) and response(Consumer) will be written to.
#For example If parseMethod = IFS, the generator will always use a generated variable 'parsePath' to set the path where the payload is written. If it has a value, then the generator will create the variable and then assign this value in the generated code. If parsePath is blank, the generator will assign a default value to the generated parsePath variable such as '/mdrest4i/payloads/{pgmname}/input.json'.
# If parseMethod = DATA-INTO for example the SDK user can specify where the payload should end up and in what format
parseIntoFormat: UTF-8
genMethod: DATA-GEN
# This will control what happens to in bound payloads. initially we will allow DATA-GEN, MDR-YAJL(used for mdr_addchar() etc), or IFS. MDR-GEN(used for MDR-DATAGEN) will be added in V14.2
genPath: '/mdrest4i/data/input.json'
# GEN logic to create payload directly from IFS. only used when parseMethod = IFS
# message text from generator API
paging: false # NOTEMP
# GEN logic to send and receive pagination headers
missingEntryHandling: false # NOTEMP
# GEN logic to for handling missing entries in request body
numExceptionBypass: true # NOTEMP
# GEN logic for exception handling of numbers from request body, too large for numeric variables
callType: MODULE # NOTEMP PROVIDER ONLY
# API ONLY: GEN logic for calling a module from API. enum: MODULE, PGM, SRVPGM.
called: # PROVIDER ONLY
# Calling details used by generator - only exists in swagger if added in UI by user.
callLib: STUART
# qualified library name for module. *LIBL can be used so no qualified name is used in generated code
callname: MYMOD
# module, service program or program name
procName: GETSTUFF
# procedure name
callparms:
# GEN logic for parameters to be passed to called program
inqry:
# parameters from query string used in call
- accountid
inhdr:
# parameters from HTTP headers used in call
- x-name
inpth:
- pathparm2
# parameters from API path used in call
schema: '#/components/schemas/parameters'
# The request body schema that should be passed with the call. the corresponding data structure is passed at the end of the parameters passed
The table below defines the UI settings and corresponding generator actions. | OAPI Extension | UI Value |MDRSDK Constant| Generator Action | |-------|----------|----------------|-------------------| |parseMethod|DATA-INTO|METHOD_DATAINTO|Use IBM's DATA-INTO function to parse data into a data structure| |parseMethod|JPATH|METHOD_JSONPATH| Use MDR_JSONPATHV etc functions to parse into a data structure| |parseMethod|IFS|METHOD_IFSSAVE|Use MDR_writeBodyToFile to save the incoming payload directly into an ifs file specified in mdrGenOptions.payloads.parseInto using mdrGenOptions.payloads.parseIntoFormat | |##########|################|################|###################################################################| |genMethod|DATA-GEN|METHOD_DATAGEN|Use IBM's DATA-GEN function to generate a JSON payload from a data structure| |genMethod|MDR-YAJL|METHOD_MDRYAJL|Use mdr_addchar etc to build payload| |genMethod|IFS|METHOD_IFSREAD|Load payl;oad directly from IFS file specified in mdrGenOptions.payloads.genPath|
x-schemaFld & x-schema
Extends: /path/method/paramters/schema Function: Both are used to tell the generator where to look for the detailed parameteter attributes for for generating RPG/COBOL Variables. we only ass detailed attributes (such as IBM i data types, size etc) in the SWAGGER schemas Example
parameters:
- in: query
name: dept
description: department
required: true
schema:
x-schemaFld: Department
# The element in the schema that this paramters relates to
x-schema: '#/components/schemas/parameters'
# The schema that this parameter relates to
- in: header
name: x-category
description: Category
required: true
schema:
x-schemaFld: Category
# The element in the schema that this paramters relates to
x-schema: '#/components/schemas/parameters'
# The schema that this parameter relates to
x-flow
Extends: /path/method/paramters/in: header Function: Specifies the usage of HTTP Headers in the transaction. Tells the generator what code to create for fetching and writing headers in request/responses. Example
parameters:
- in: query
name: dept
description: department
required: true
schema:
x-schemaFld: Department
x-schema: '#/components/schemas/parameters'
- in: header
name: x-category
description: Category
required: true
schema:
x-schemaFld: Category
x-schema: '#/components/schemas/parameters'
x-flow: both
# Tells the generator what HTTP Header handling code to create. enum: in, out, both
x-ibmitype & x-column
Extends: /components/schemas/[mdlDummy]/properties/[REFUUID] Function: Specifies PF/TABLE name and Library that the schema was built from. Tells the generator where to get the variable attributes when building payload data structures. Also used to create SQL reads for GET methods where the schema is the explicit (norefs) payload. Example
components:
schemas:
mdlDummy:
properties:
refuuid:
description: REFUUID
type: string # used by generator set type dat element: variable, data structure, array
maxLength: 50 # used by generator to set char/varchar length
x-ibmitype: varchar
x-column: REFUUID
envname:
description: ENVNAME
type: string
maxLength: 250
x-ibmitype: varchar
x-column: ENVNAME
type:
description: TYPE
type: string
maxLength: 1
x-ibmitype: char
x-column: TYPE
mdcmsurl:
description: MDCMSURL
type: string
maxLength: 256
x-ibmitype: char
x-column: MDCMSURL
timestamp:
description: TIMESTAMP
type: string
format: date
maxLength: 26
x-column: TIMESTAMP
decfld:
description: DECFLD
type: number
x-ibmitype: packed
maximum: 99999999.99
x-column: DECFLD
decfld1:
description: DECFLD1
type: integer
x-ibmitype: packed
maximum: 9999999999
x-column: DECFLD1
numfld:
description: NUMFLD
type: integer
x-ibmitype: zoned
maximum: 134217727
x-column: NUMFLD
type: object
X-mdrschema
Extends: /components/schemas/[mdlSQLex] Function: Specifies the source of the SQL, COBOL, RPGLE used to create the SWAGGER schema, and the SDK path that stores the SQL code to be used to insert in generated API/CONSUMER MDRSDK Usage: MDRSDK would return these values as part of MDRSDK_readschema() function. The following data structures apply:
dcl-ds MDRSDK_schemaExtensions_t qualified template;
type varchar(30) inz;
objectPath varchar(4094) inz;
srcPath varchar(4094) inz;
sdksrcpath varchar(4094) inz;
end-ds;
dcl-pr MDRSDK_readSchema ind extproc(*cwiden:MDRSDK_env.readSchema);
cfg likeds(MDRSDK_plugin_t);
handle pointer value;
prop likeds(MDRSDK_schemaProp_t);
extensions likeds(MDRSDK_schemaExtensions_t);
end-pr;
components:
schemas:
mdlRespDB2:
x-mdrschema: # Provides reference information that the SDK used to extract the schema. For SQL this information is used by the generator to create the SQL statements
type: DB2 # has different possible values based upon what reverse engineering tools available. Currently DB2, DS-RPGLE, DS-COBOL, SQL
objectPath: "/QSYS.LIB/MDRTST14.LIB/LXCLIENT.FILE" # path to object used to create schema. currently this is only applicable when using DB2 "Type"
srcpath: "" # Original source used by SDK UI to create schema via reverse engineering apis such as MDRSCHEMA, MDRGENSCM, MDRFIELDS etc
sdksrcpath: "" # The SDK saves the imported SQL to this path. The generator will use this exact SQL code to insert the sql statement in the generated API/Consumer, rather than the source from the original source member/folder etc. This avoids mismatches if the source is changed between import and code generation.
##############################
mdlRespDSExtract:
x-mdrschema:
type: DS-RPGLE
objectPath: ""
srcpath: "/qsys.lib/mdrtst14.lib/examples.file/SCMR001.mbr"
sdksrcpath: ""
##############################
mdlRespDSCOBOLExtract:
x-mdrschema:
type: DS-COBOL
objectPath: ""
srcpath: "/qsys.lib/mdrtst14.lib/examples.file/SCMC001.mbr"
sdksrcpath: ""
##############################
mdlRespSQLmbrExtract:
x-mdrschema:
type: SQL
objectPath: ""
srcpath: "/qsys.lib/mdrtst14.lib/examples.file/scmq001.mbr"
sdksrcpath: "/www/mdrstt12/specs/cons/STUART/SQL87dd3e0.sql"
##############################
mdlRespSQLLocalExtract:
x-mdrschema:
type: SQL
objectPath: ""
srcpath: ""
sdksrcpath: "/www/mdrstt12/specs/cons/STUART/SQL87dd3e0.sql"