Developing z/OS applications to call APIs

You can develop CICS®, IMS and other z/OS applications to call RESTful APIs. Both COBOL and PL/I languages are supported.

To communicate with the IBM® z/OS Connect server and call an API, you must modify your z/OS application to include the required data structures, prepare the data for the API request, call the communication stub, and handle the response.

Before you begin

Use the build toolkit to generate the API requester artifacts, follow the instructions in Generating artifacts for an API requester from the command line.
Note:
  1. For COBOL applications, RTEREUS must be set to off as it is unsupported when calling BAQCSTUB.
  2. For long running API requester applications that use the IMS or z/OS communication stub, the BAQCTERM function must be called to close and clear the cached connection that is used by IBM z/OS Connect. Follow step 7 to ensure that your application BAQCSTUB connections are closed after the application module for your program is unloaded.
  3. Compile your z/OS applications with the RENT option. This is required by both IBM z/OS Connect and the Web Toolkit that it uses.
  4. For COBOL applications, use the SYNCHRONIZED or SYNC clause for data structures to align data during transformation in the IBM z/OS Connect server.

About this task

To call an API from your z/OS application, you must include the following:
  • The data structures specific to the API operation generated from the build toolkit for the operation in the API to be called. These consist of the request and response data structures and the API information file. You can use the summary report or the console log generated by the build toolkit to identify the names of the generated artifacts for each operation.
  • Either the COBOL copybook BAQRINFO as provided in the hlq.SBAQCOB data set or the PL/I include file BAQRINFP as provided in the hlq.SBAQPLI data set. You must ensure that the data set for your application is in the SYSLIB concatenation for the compilation JCL.

    The following table shows the communication stub data structures to use in your application:
    Table 1. Data structures to pass to the communication stub
    BAQRINFO copybook COBOL data structures BAQRINFP include file PL/I data structures Description
    BAQ-REQUEST-INFO BAQ_REQUEST_INFO For passing security parameters to the API request.
    BAQ-RESPONSE-INFO BAQ_RESPONSE_INFO For passing the return code, status code and status message back to the calling application.
    The BAQ-REQUEST-INFO data structures contain a compatibility level, BAQ-REQUEST-INFO-COMP-LEVEL for COBOL and BAQ_REQUEST_INFO_COMP_LEVEL for PL/I. The following table shows the supported levels:
    Table 2. BAQ-REQUEST-INFO Compatibility levels
    Compatibility Level Description
    0 The initial value, no additional parameters are supported.
    1 Support for OAuth 2.0 parameters, see OAuth 2.0 parameters.
    2 Support for JSON Web Token parameters, see JWT parameters.
    3 Support for dynamic routing to IBM z/OS Connect servers from CICS, see Overriding the URIMAP in a CICS application.
    4 Support for OAuth 2.0 resource, audience and custom parameters,. For more information, see OAuth 2.0 parameters.
    5 Support for JSON Web Token custom parameters and custom headers. For more information, see JWT parameters.

    The higher compatibility levels automatically support the parameters enabled by the lower compatibility levels.

IBM z/OS Connect supplies sample programs that demonstrate how to call APIs through the IBM z/OS Connect server in the hlq.SBAQSAMP data set. The samples contain comments to help you write your own applications. For COBOL, the sample program is BAQCAPPO; for PL/I, the sample program is BAQCAPPP.

Tip: You can use the communication stub trace as an aid with your application development. For more information, see Enabling trace in communication stubs.

Procedure

The following steps demonstrate how to call an operation of an API from a COBOL program, using the communication stub.

  1. Include the BAQRINFO data structure.
    Add the line COPY BAQRINFO into the WORKING-STORAGE-SECTION of your z/OS application program.
    COPY BAQRINFO
  2. Include the request data structure, response data structure and the API information file that have been generated for the operation you want to call.
    Assuming the request data structure is API00Q01, the response data structure is API00P01, and the API information file is API00I01, insert the following code snippet:
    
    01 REQUEST.
          COPY API00Q01.
    01 RESPONSE.
          COPY API00P01.
    01 API-INFO.
          COPY API00I01.
    
  3. Declare variables for the request, response and communication stub.
    The following table shows the variables that you need to declare for the request and response. You can choose your own variable names.
    Table 3. Variables to declare
    Variables for COBOL Description
    BAQ-REQUEST-PTR Pointer to the storage for request messages.
    BAQ-REQUEST-LEN Size of the storage for request messages.
    BAQ-RESPONSE-PTR Pointer to the storage for the response message.
    BAQ-RESPONSE-LEN Size of the storage for the response message.
    COMM-STUB-PGM-NAME Program name of the communication stub. The value of the variable must be set to BAQCSTUB.
    COMM-TERM-PGM-NAME Used to close the reusable connection of BAQCSTUB after IMS unloads the application module. The value of the variable must be set to BAQCTERM.

    For example, insert the following code snippet:

    
    01 BAQ-REQUEST-PTR             USAGE POINTER.
    01 BAQ-REQUEST-LEN             PIC S9(9) COMP-5 SYNC.
    01 BAQ-RESPONSE-PTR            USAGE POINTER.
    01 BAQ-RESPONSE-LEN            PIC S9(9) COMP-5 SYNC.
    77 COMM-STUB-PGM-NAME          PIC X(8) VALUE 'BAQCSTUB'.
    77 COMM-TERM-PGM-NAME          PIC X(8) VALUE 'BAQCTERM'.
    Note: If the request or response message is empty, you must set the pointer to NULL and set the storage size to 0, for example, for an empty COBOL request, set BAQ-REQUEST-PTR to NULL and set BAQ-REQUEST-LEN to 0.
  4. Populate values for the request.
    1. Assuming Xtext is a parameter in the request data structure API00Q01, insert the following code line:
      MOVE 'How are you' TO Xtext
      Tip: To populate values for a request that contains fields of array or string, you can refer to Sample: Specifying values for arrays and strings.
    2. Specify values for the variables that have been declared for the request and response in Step 3.
      
      SET BAQ-REQUEST-PTR TO ADDRESS OF REQUEST.
      MOVE LENGTH OF REQUEST TO BAQ-REQUEST-LEN.
      SET BAQ-RESPONSE-PTR TO ADDRESS OF RESPONSE.
      MOVE LENGTH OF RESPONSE TO BAQ-RESPONSE-LEN.
      
  5. Call the communication stub with the required parameters.

    In this example, dynamic linkage is used by the CALL identifier statement, where identifier is a variable called COMM-STUB-PGM-NAME for the BAQCSTUB load module. The variable is declared in Step 3 with the value of 'BAQCSTUB'.

    
    CALL COMM-STUB-PGM-NAME USING
          BY REFERENCE API-INFO
          BY REFERENCE BAQ-REQUEST-INFO
          BY REFERENCE BAQ-REQUEST-PTR
          BY REFERENCE BAQ-REQUEST-LEN
          BY REFERENCE BAQ-RESPONSE-INFO
          BY REFERENCE BAQ-RESPONSE-PTR
          BY REFERENCE BAQ-RESPONSE-LEN.
    
  6. Retrieve the values from the response.
    
    IF BAQ-SUCCESS THEN
            DISPLAY "The program call is successful. "
         ELSE
            EVALUATE TRUE
              WHEN BAQ-ERROR-IN-API
                DISPLAY "API RETURN ERROR: " BAQ-STATUS-CODE
                DISPLAY "API RETURN ERROR MESSAGE: "
                   BAQ-STATUS-MESSAGE(1:BAQ-STATUS-MESSAGE-LEN)
              WHEN BAQ-ERROR-IN-ZCEE
                DISPLAY "Z/OS CONNECT RETURN ERROR: " BAQ-STATUS-CODE
                DISPLAY "SERVER RETURN ERROR MESSAGE: "
                   BAQ-STATUS-MESSAGE(1:BAQ-STATUS-MESSAGE-LEN)
              WHEN BAQ-ERROR-IN-STUB
                DISPLAY "STUB RETURN ERROR: " BAQ-STATUS-CODE
                DISPLAY "STUB RETURN ERROR MESSAGE: "
                   BAQ-STATUS-MESSAGE(1:BAQ-STATUS-MESSAGE-LEN)
            END-EVALUATE
         END-IF.
    

    A return code and a status code are included in the BAQ-RESPONSE-INFO structure. BAQ-RETURN-CODE indicates whether the request was successful or not, and if not where the error originated. In a COBOL program, the special variable RETURN-CODE is set to the value of BAQ-RETURN-CODE. BAQ-STATUS-CODE gives the HTTP status response code. In the sample code, details of the success or failure of the call are written to the job log. For more information about error handling, see Error handling for API requester calls.

  7. If you have any long running API requester applications that use the IMS or z/OS communication stub and cached connections, you must close and clear the cached connection by calling the BAQCTERM function.
    A program that issues one or more API requester calls must call BAQCTERM when it completes its API requester work. If BAQCTERM is not called, the connection that was used by BAQCSTUB is not closed and the memory it owns is not reusable until the IMS or z/OS communication process ends. The following example shows how to call the BAQCTERM function at the logical end of your application.
    CALL COMM-TERM-PGM-NAME USING
          BY REFERENCE BAQ-RESPONSE-INFO.
    
    IF BAQ-SUCCESS THEN
            DISPLAY "The BAQCSTUB connection has been terminated."
         ELSE
            EVALUATE TRUE
              WHEN BAQ-ERROR-IN-API
                DISPLAY "API RETURN ERROR: " BAQ-STATUS-CODE
                DISPLAY "API RETURN ERROR MESSAGE: "
                   BAQ-STATUS-MESSAGE(1:BAQ-STATUS-MESSAGE-LEN)
              WHEN BAQ-ERROR-IN-ZCEE
                DISPLAY "Z/OS CONNECT RETURN ERROR: " BAQ-STATUS-CODE
                DISPLAY "SERVER RETURN ERROR MESSAGE: "
                   BAQ-STATUS-MESSAGE(1:BAQ-STATUS-MESSAGE-LEN)
              WHEN BAQ-ERROR-IN-STUB
                DISPLAY "STUB RETURN ERROR: " BAQ-STATUS-CODE
                DISPLAY "STUB RETURN ERROR MESSAGE: "
                   BAQ-STATUS-MESSAGE(1:BAQ-STATUS-MESSAGE-LEN)
            END-EVALUATE
         END-IF.
    

    As in step 6, if the BAQCSTUB connection ends successfully, the job log indicates that the connection termination is successful; otherwise, the job log displays the detailed error message.

Results

The COBOL application program is enabled to call the operation of the API using the communication stub.

What to do next

  • Refer to Testing the z/OS application for API calls to compile and run your z/OS application program to call the API.
  • If the RESTful API that you want to call is secured with OAuth 2.0, a JWT, or an API key, you must make some other modifications to your z/OS application to ensure the required parameters are provided in the API request. For more information, see Calling secured RESTful APIs.