Using additionalProperties

If additionalProperties is set within an object type description within an OpenAPI schema definition, then additional properties can be used that are not described with the properties section of the type object schema. This allows for dynamic properties to be used during the life of the API that is not formally described. See https://swagger.io/specification/v3/ for full details.

zosConnect-3.0 Applies to zosConnect-3.0.

Started task Applies to z/OS Connect Servers run by using a z/OS started task procedure.

additionalProperties can be defined in any valid OpenAPI 2.0 and OpenAPI 3.0 specification format when they are defined in a type object OpenAPI schema definition. Once specified, z/OS Connect API requester allows additional properties of any valid JSON type to be sent to an API or received from an API by using a COBOL or PL/I array structure.

The following OpenAPI 3.0 document example is provided in JSON and YAML format. In this example, the operation1 operation specifies additionalProperties in the root of the requestBody schema. The 200 response schema specifies additionalProperties at the root level and at a nested level in an array in the department property and in an object in the pay property.

OpenAPI.json
{
    "openapi": "3.0.0",
    "info": {
        "title": "characterStrings",
        "version": "1.0.0"
    },
    "paths": {
        "/operation1": {
            "put": {
                "operationId": "operation1",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "array",
                                "items": {
                                    "type": "object",
                                    "additionalProperties": true,
                                    "required": [
                                        "name"
                                    ],
                                    "properties": {
                                        "name": {
                                            "type": "string"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "Successful operation",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "additionalProperties": true,
                                    "required": [
                                        "name"
                                    ],
                                    "properties": {
                                        "name": {
                                            "type": "string"
                                        },
                                        "lastName": {
                                            "type": "string"
                                        },
                                        "department": {
                                            "type": "array",
                                            "items": {
                                                "type": "object",
                                                "additionalProperties": true,
                                                "properties": {
                                                    "name": {
                                                        "type": "string"
                                                    },
                                                    "deptId": {
                                                        "type": "string"
                                                    },
                                                    "objField": {
                                                        "type": "object",
                                                        "properties": {
                                                            "objItem": {
                                                                "type": "integer"
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        },
                                        "pay": {
                                            "type": "object",
                                            "additionalProperties": true,
                                            "properties": {
                                                "salary": {
                                                    "type": "number",
                                                    "format": "double"
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

OpenAPI.yaml

---
openapi: 3.0.0
info:
  title: characterStrings
  version: 1.0.0
paths:
  "/operation1":
    put:
      operationId: operation1
      requestBody:
        content:
          application/json:
            schema:
              type: array
              items:
                type: object
                additionalProperties: true
                required:
                - name
                properties:
                  name:
                    type: string
        required: true
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
                required:
                - name
                properties:
                  name:
                    type: string
                  lastName:
                    type: string
                  department:
                    type: array
                    items:
                      type: object
                      additionalProperties: true
                      properties:
                        name:
                          type: string
                        deptId:
                          type: string
                        objField:
                          type: object
                          properties:
                            objItem:
                              type: integer
                  pay:
                    type: object
                    additionalProperties: true
                    properties:
                      salary:
                        type: number
                        format: double

Using additionalProperties with the API requester Gradle plug-in

The API requester Gradle plug-in detects OpenAPI 3.0 document operations that specify additionalProperties. The generated COBOL copybooks or PL/I include files for these operations contain array fields for setting additional properties on a request and receiving additional properties on response. The array size is set to 20, allowing 20 additional property names and values to be sent or received. The additionalPropertiesSize optional property controls the size of the field within the array. This optional property needs to be large enough to store the additional property name and value.

For more information on using the API requester Gradle plug-in, see Generating the language structures for an API requester.

Examples of generated COBOL copybook for additionalProperties

Using the example OpenAPI document in this topic, the API requester Gradle plug-in generates the request COBOL copybook as shown in the following example.
         01 BAQBASE-API00Q01.
            03 requestBody-num               PIC S9(9) COMP-5 SYNC.
            03 requestBody-dataarea          PIC X(16).
         01 API00Q01-requestBody.
            03 requestBody.
              06 name-length                   PIC S9999 COMP-5 SYNC.
              06 name                          PIC X(255).
              06 requestBody-props-num         PIC S9(9) COMP-5 SYNC.
              06 requestBody-props OCCURS 20.
                09 requestBody-json-property     PIC X(255).

In this example, the Gradle plug-in property additionalPropertiesSize was not specified in the options.yaml file, so the default value 255 is used as the length of the generated requestBody-json-property field.

Where the requestBody-props-num field indicates the number of additional properties to be sent in the root of the request body. These additional properties are set in the requestBody-props array. Each requestBody-json-property contains an additional property name and value.

The supplied additional property can be any valid JSON property form that uses values of string, number, Boolean, object, or array. For example,
  • "myprop": "myvalue"
  • "myprop": 12
  • "myprop": true
  • "myprop": { "myobjectprop": "z" }
  • "myprop": [ "item1", "item2" ]
The following COBOL example shows setting 2 additional properties on the request.
  1. "author" with a string value of "A. N. Author".
  2. "isbn" with a numeric value of 2234243345.
           MOVE 2 TO requestBody-props-num OF BAQBASE-API00Q01.
           MOVE '"author":"A. N. Author"' TO
            requestBody-json-property(1).
           MOVE '"isbn":2234243345' TO
            requestBody-json-property(2).
Using the example OpenAPI document in this topic, the API requester Gradle plug-in generates the response COBOL copybook as shown in the following example..
        01 BAQBASE-API00P01.
          03 responseCode200-existence     PIC S9(9) COMP-5 SYNC.
          03 responseCode200-dataarea      PIC X(16).
        01 API00P01-responseCode200.
          03 responseCode200.
            06 name-length                   PIC S9999 COMP-5 SYNC.
            06 name                          PIC X(255).
            06 lastName-existence            PIC S9(9) COMP-5 SYNC.
            06 lastName.
              09 lastName2-length              PIC S9999 COMP-5 SYNC.
              09 lastName2                     PIC X(255).
            06 department-num                PIC S9(9) COMP-5 SYNC.
            06 department-dataarea           PIC X(16).
            06 pay2-existence                PIC S9(9) COMP-5 SYNC.
            06 pay.
              09 salary-existence              PIC S9(9) COMP-5 SYNC.
              09 salary                        COMP-2 SYNC.
              09 pay-props-num                 PIC S9(9) COMP-5 SYNC.
              09 pay-props OCCURS 20.
                12 pay-json-property             PIC X(255).
            06 responseCode200-props-num     PIC S9(9) COMP-5 SYNC.
            06 responseCode200-props OCCURS 20.
              09 responseCode200-json-propert  PIC X(255).
        01 API00P01-department.
          03 department.
            06 name-existence                PIC S9(9) COMP-5 SYNC.
            06 name.
              09 name2-length                  PIC S9999 COMP-5 SYNC.
              09 name2                         PIC X(255).
            06 deptId-existence              PIC S9(9) COMP-5 SYNC.
            06 deptId.
              09 deptId2-length                PIC S9999 COMP-5 SYNC.
              09 deptId2                       PIC X(255).
            06 objField2-existence           PIC S9(9) COMP-5 SYNC.
            06 objField.
              09 objItem-existence             PIC S9(9) COMP-5 SYNC.
              09 objItem                       PIC S9(18) COMP-5 SYNC.
            06 department-props-num          PIC S9(9) COMP-5 SYNC.
            06 department-props OCCURS 20.
              09 department-json-property      PIC X(255).

Where

  • The responseCode200-props-num field indicates the number of additional properties that are received at the root level of the response body. These additional properties are available in the responseCode200-props array. Each responseCode200-json-propert contains an additional property name and value.
  • The pay-props-num field indicates the number of additional properties that are received in the nested pay object in the response body. These additional properties are available in the pay-props array. Each pay-json-property contains an additional property name and value.
  • The department-props-num field indicates the number of additional properties that are received in the nested department property array in the response body. These additional properties are available in the department-props array. Each department-json-property contains an additional property name and value.

What next?

  • You might want to learn how to use PATCH to perform partial updates in your applications. See procedures CD-PATCH-REDBOOK and CE-MERGE-REDBOOK for examples on how to update a Redbook by using RFC6902 and RFC 7396 patch documents. For more information, see Using the PATCH HTTP method in an application.