z/OS Connect - Group home

Making a REST API call from IMS using zOS Connect

  

From an IMS batch or transactional application, calls can be made to retrieve or update JSON data maintained by an OpenAPI 3 described REST API. Using COBOL or PL/I data structures, IMS application requests can be made to an API and responses received back to COBOL or PL/I data structures. This provides a seamless integration of API JSON data into the IMS programming language with the data types you are used to.

In this blog we will use the z/OS Connect API requester sample tutorial to highlight the concepts. The sample can be obtained from https://github.com/zosconnect/sample-oas3-requester/tree/main or via your SMP/E install as a zip named sample-oas3-requester.zip. The sample includes COBOL and PL/I programs for IMS, CICS TS and z/OS batch environments.

The start point in calling any REST API is the OpenAPI 3 document that describes the API, this is broken down with URL paths and HTTP Methods. Each distinct Path and Method combination is known as an operation and generally has an operation id to distinguish it. In the sample under folders RedbookApi and RedbookApiPLI within the src/main/api directory is the file redbookapi.yaml. It’s the same file in both locations. This is the OpenAPI document that describes our sample REST API. The API is based on a simple Redbook management API.

The paths described in the document identify the set of resources being used by the API, /redbook/{title} for operations against a single Redbook and path /redbooks for an operation involving all redbooks.

The HTTP method describes the type of operation we want to perform on a single resource or group of resources. 

  • GET - Retrieve a resource, data about a Redbook in our case

  • POST - Create a new resource in the APIs data store

  • PUT - Update an existing resource with new content in the data store

  • DELETE - Delete a resource from the APIs data store

In our sample API, we can get details of a particular Redbook using operationid getRedbook, we can create a new Redbook using operationid createRedbook, and finally get data on all the Redbooks in the APIs data store using operationid getAllRedbooks. For a complete understanding of all of the facets of the OpenAPI document consult the OpenAPI 3 specification document.

Under the samples RedbookApi and RedbookApiPLI folder is directory src/main/config with a file options.yaml. These files are mostly similar but do define the language choice for the API calling application, COBOL or PL/I. This file is known as the API requester Gradle plugin options. In this file, various options can be supplied that affect how the language structures are generated. See the z/OS Connect documentation for full details of all the options available at https://www.ibm.com/docs/en/zos-connect/zos-connect/3.0?topic=requester-api-gradle-plug-in-properties-options. Also this blog (https://community.ibm.com/community/user/ibmz-and-linuxone/blogs/ian-hodges/2023/07/25/generating-better-cobol-language-structures-with-z?CommunityKey=05a9c234-d770-4c28-b878-b8550562327b) describes how setting various OpenAPI document attributes and Gradle plugin options affect how the COBOL and PL/I data structures are generated.

With the OpenAPI document and associated option properties set in specific file locations, the API requester Gradle plugin can be used via the build.gradle file (located in the RedbookAPI and RedbookApiPLI directories). Executing the API requester Gradle plugin via a Gradle build generates a number of artefacts. A WAR file is generated that contains control information for z/OS Connect to use at runtime to call the REST API. This WAR file is deployed to a z/OS Connect Server to enable the onward call to a REST API operation. Also generated are COBOL or PL/I language structures that contain the data descriptions of any request or response data for each operation described in the OpenAPI document.

With these artefacts generated, the COBOL or PL/I application program can be written. In the sample, there are two IMS programs BAQHRBKB and BAQHRBKT for IMS batch and transactional. There are versions of the programs for COBOL and PL/I. In these programs you can see the the copybooks generated by the API requester Gradle plugin are referenced. There are either two or three files based on the APIs inputs and outputs. Those suffixed I01 are the API-INFO language structure that contains static information required by z/OS Connect to make the REST API call for the operation. Those suffixed Q01 are any request structures and those suffixed P01 are any response structures. Both are optional based on the API operation description.

The programs follow a similar structure with differences for the IMS execution environment. For any API operation call the z/OS Connect HostAPI verbs are used from the application program to make the call. They are as follows.

BAQINIT - This verb is used to make a connection from the IMS application to a z/OS Connect Server processing the API requests. The details of where the z/OS Connect Server is located are passed via environment variables defined to the IMS process. See (https://www.ibm.com/docs/en/zos-connect/zos-connect/3.0?topic=requesters-configuring-ims-access-zos-connect-api-calls) for details. Depending on how your application is architected you may make a connection and execute a single API call and then terminate the connection, or make multiple API calls before terminating the connection.

BAQEXEC- This verb makes the REST API call via the z/OS Connect Server. Prior to making the call, the request structure suffixed Q01 for the operation, may need to be set up depending on the operations needs. For example, for the getRedbook operation the Title of the Redbook must be supplied and optionally an Authors name. With the request structure set the BAQEXEC call is called from the IMS application. BAQEXEC takes the request structure, the response structure and the API-INFO structure and using the z/OS Connect Server information supplied via configuration calls the z/OS Connect Server.

The z/OS Connect Server locates the operation id supplied via the API-INFO structure and uses this to find the WAR file content loaded on the server. The WAR files content is used by z/OS Connect to convert the binary COBOL or PL/I request data to JSON form and this JSON data is mapped to the REST API requirements of path parameters, headers, query parameters and request body. z/OS Connect then calls the REST API using the <zosconnect_endpoint> server.xml configuration and the API-INFO data. The REST API will respond as appropriate and z/OS Connect will map the response to a defined JSON form and this JSON is then converted to binary COBOL or PL/I response data. The BAQEXEC call terminates and the IMS application can examine the REST API status code and the response data.

The response will contain optional sections, one per defined response status code, and possibly one per dynamically sized array. These sections are known as Data Areas and we use the BAQGETN verb to retrieve data from the specified Data Area one element at a time.

BAQFREE - This is an optional verb used to deallocate resources used by the BAQEXEC verb, prior to making another BAQEXEC call or terminating the connection. Both BAQEXEC and BAQTERM will automatically call BAQFREE if it has not been explicitly called by the application.

Finally BAQTERM is called to close the connection to z/OS Connect after which no further API calls can be made until BAQINIT is called again.

Pictorially the flow is as follows:

For full details of the Redbook sample tutorial see https://www.ibm.com/docs/en/zos-connect/zos-connect/3.0?topic=gst-creating-zos-connect-api-requester-project-zos-application and for the API requester reference in the z/OS Connect documentation https://www.ibm.com/docs/en/zos-connect/zos-connect/3.0?topic=calling-apis-from-zos-applications