Showing posts with label mainframe integration. Show all posts
Showing posts with label mainframe integration. Show all posts

Saturday, 14 March 2026

COBOL REST API Calls: CICS and z/OS Connect Examples

EXEC CICS WEB CONVERSE can return a normal CICS response while the server returns HTTP 404, 429, or 500. A COBOL program must therefore check both the CICS RESP value and the HTTP STATUSCODE before it accepts the response body.

On z/OS, two common requester paths are the CICS WEB API and IBM z/OS Connect API requesters. The right choice depends on where the program runs, whether an OpenAPI document is available, and who should own JSON conversion.

COBOL REST API call flow through CICS WEB CONVERSE or z/OS Connect API requester
COBOL can call a REST endpoint through CICS WEB commands or a generated z/OS Connect API requester.

Choose the COBOL REST requester path

Option Good fit Data handling Program responsibility
CICS WEB API A CICS application needs direct control of HTTP requests. The program builds and parses JSON, or calls a helper routine. HTTP method, headers, status, body, TLS configuration, timeout, and retry policy.
z/OS Connect API requester An OpenAPI definition exists and generated COBOL structures are preferred. z/OS Connect maps COBOL data structures to and from JSON. Populate generated copybooks, call the requester interface, and inspect BAQ completion data.

Use the CICS tutorial index if EXEC CICS command handling is new to you. The older COBOL web-services interface overview covers the wider topic of consuming and exposing services. This article stays with outbound REST calls.

CICS outbound HTTP flow

  1. Open a client connection with WEB OPEN, or use a URIMAP that holds the endpoint and certificate settings.
  2. Write request headers such as Content-Type, Accept, and authorization values when the service needs them.
  3. Send the request and receive the response with WEB CONVERSE.
  4. Check RESP, RESP2, the HTTP status code, and the returned body length.
  5. Close the connection with WEB CLOSE, unless the site's connection-pooling design manages reuse.

CICS uses a session token to identify the connection. IBM also documents code-page conversion between EBCDIC and ASCII for CICS web support. Treat encoding as part of the interface contract; do not assume every JSON payload already matches the program's data representation.

CICS WEB CONVERSE GET example

The following fragment shows the control flow. Field definitions, command options, URIMAP names, and supported HTTP versions must match the installed CICS release.

       WORKING-STORAGE SECTION.
       01  WS-SESSION-TOKEN       PIC X(8).
       01  WS-RESP                PIC S9(8) COMP.
       01  WS-RESP2               PIC S9(8) COMP.
       01  WS-HTTP-STATUS         PIC S9(8) COMP.
       01  WS-BODY-LENGTH         PIC S9(8) COMP VALUE 8192.
       01  WS-RESPONSE-BODY       PIC X(8192).

           EXEC CICS WEB OPEN
                HOST('api.example.com')
                SCHEME(HTTPS)
                PORTNUMBER(443)
                SESSTOKEN(WS-SESSION-TOKEN)
                RESP(WS-RESP)
                RESP2(WS-RESP2)
           END-EXEC

           IF WS-RESP = DFHRESP(NORMAL)
              EXEC CICS WEB CONVERSE
                   SESSTOKEN(WS-SESSION-TOKEN)
                   PATH('/v1/customers/4711')
                   METHOD(GET)
                   INTO(WS-RESPONSE-BODY)
                   TOLENGTH(WS-BODY-LENGTH)
                   STATUSCODE(WS-HTTP-STATUS)
                   RESP(WS-RESP)
                   RESP2(WS-RESP2)
              END-EXEC
           END-IF

           IF WS-RESP = DFHRESP(NORMAL)
              AND WS-HTTP-STATUS >= 200
              AND WS-HTTP-STATUS < 300
                CONTINUE
           ELSE
                PERFORM REPORT-API-FAILURE
           END-IF

           EXEC CICS WEB CLOSE
                SESSTOKEN(WS-SESSION-TOKEN)
           END-EXEC

A successful WEB OPEN does not prove that the later request will succeed. IBM lists conditions such as IOERR, NOTAUTH, NOTOPEN, TIMEDOUT, and TOKENERR for web commands. Record RESP and RESP2 with a request identifier so support staff can match the COBOL event to server logs.

Send a JSON POST from COBOL

Enterprise COBOL can create a JSON document from a COBOL group item with JSON GENERATE. Check JSON-CODE and the exception phrase before sending the document.

       01  CUSTOMER-REQUEST.
           05  CUSTOMER-ID        PIC X(10).
           05  CUSTOMER-STATUS    PIC X(8).
       01  JSON-REQUEST           PIC X(4096).
       01  JSON-BYTES             PIC 9(9) COMP.

           MOVE '4711'     TO CUSTOMER-ID
           MOVE 'ACTIVE'   TO CUSTOMER-STATUS

           JSON GENERATE JSON-REQUEST
                FROM CUSTOMER-REQUEST
                COUNT IN JSON-BYTES
             ON EXCEPTION
                DISPLAY 'JSON GENERATE FAILED, JSON-CODE=' JSON-CODE
           END-JSON

For the HTTP call, set Content-Type: application/json, pass only the generated byte count, and use METHOD(POST). Confirm whether the service requires UTF-8. IBM documents UTF-8 support for JSON GENERATE and JSON PARSE, but compiler level and data definitions still matter.

Parse a JSON response safely

Do not parse an error page as if it were the expected JSON object. Check the HTTP status and response Content-Type first. Then map the body to a COBOL group with JSON PARSE and test JSON-CODE.

       01  CUSTOMER-RESPONSE.
           05  RESPONSE-ID        PIC X(10).
           05  RESPONSE-STATUS    PIC X(8).

           JSON PARSE WS-RESPONSE-BODY
                INTO CUSTOMER-RESPONSE
             ON EXCEPTION
                DISPLAY 'JSON PARSE FAILED, JSON-CODE=' JSON-CODE
           END-JSON

Treat the snippets as patterns, not drop-in production modules. Generated JSON names, truncation behavior, OMITTED fields, UTF-8 definitions, and compiler options should be tested with payloads from the actual API.

z/OS Connect API requester flow

An API requester starts with an OpenAPI document. The z/OS Connect build tools generate artifacts that include COBOL copybooks for the request and response structures. At runtime, the COBOL program fills the request fields and calls the supplied requester interface; z/OS Connect converts the binary structures to JSON, calls the endpoint, and converts the JSON response back to COBOL fields.

  1. Validate the provider's OpenAPI document and agree on operation IDs, formats, required fields, and response codes.
  2. Generate the requester artifacts for the installed z/OS Connect level.
  3. Deploy and configure the requester with its endpoint, TLS, and authentication settings.
  4. Copy generated language structures into the COBOL application.
  5. Populate the request, execute the generated call sequence, and inspect both API and BAQ results.

The BAQHAREC copybook supplies BAQ-ZCON-COMPLETION-CODE plus reason and message fields. IBM defines condition names for success, warning, error, severe error, and a nonrecoverable condition. Log all returned diagnostic fields; the numeric completion value alone may not explain the failure.

TLS and credentials

Use HTTPS for production endpoints. In CICS, a URIMAP can hold client connection settings and can name a client certificate. IBM documents basic authentication, proxy authentication, and TLS client certificates for CICS acting as an HTTP client.

Basic credentials are encoded, not encrypted. They should travel only over TLS and should not be hard-coded in COBOL source, JCL, or SYSOUT. Store secrets in the approved security facility, limit who can read them, and plan certificate renewal before the expiry date.

Handle transport, HTTP, and application errors separately

Layer Example COBOL action
CICS transportTIMEDOUT or IOERRRecord RESP/RESP2; retry only when policy permits.
HTTP401, 404, 429, or 503Branch by status; do not treat the body as a normal response.
JSONMalformed or incompatible payloadCheck JSON-CODE; retain a redacted sample for diagnosis.
z/OS ConnectBAQ warning or errorInspect completion, reason, and message fields.
ApplicationHTTP 200 with a rejected business stateValidate response fields before updating local records.

Timeouts, retries, and duplicate requests

A retry can submit the same POST twice. Before retrying a create or payment request, find out whether the API accepts an idempotency token. GET requests are usually safer to retry, but the program still needs a retry limit and delay. A transaction should not wait forever while an endpoint is unavailable.

When CICS connection pooling is configured, it can avoid a new connection and TLS handshake for every request. Measure response time and connection use with the real workload. Do not keep a CICS task open across uncontrolled waits.

Common mistakes

  • Checking only RESP = DFHRESP(NORMAL) and ignoring HTTP STATUSCODE.
  • Sending the full 4,096-byte buffer instead of the generated JSON length.
  • Assuming the response is JSON when a proxy returned HTML.
  • Logging bearer tokens, passwords, account data, or an entire customer payload.
  • Retrying POST requests without a duplicate-request policy.
  • Hard-coding a certificate label or endpoint in several programs.
  • Moving generated z/OS Connect copybooks without the matching runtime artifacts.

Production review checklist

  • Test 2xx, 4xx, 5xx, timeout, bad certificate, invalid JSON, and oversized-response cases.
  • Set a maximum response size and detect truncation.
  • Mask tokens and personal data in messages, dumps, and traces.
  • Record a correlation ID, endpoint name, method, status, elapsed time, RESP, and RESP2.
  • Agree on retryable status codes and the maximum attempt count.
  • Confirm the API version and generated requester artifacts during deployment.
  • Include compile and regression checks in the mainframe CI/CD pipeline.

Frequently asked questions

Can COBOL call a REST API directly?

A COBOL program running in CICS can use CICS WEB commands to act as an HTTP client. Other z/OS runtimes can use facilities such as an IBM z/OS Connect API requester or the z/OS client web enablement toolkit.

Does a normal CICS RESP mean the REST call succeeded?

No. It means the CICS command completed normally. The program must also inspect the HTTP status and validate the response data.

Who converts COBOL data to JSON?

With direct CICS HTTP calls, the application can use Enterprise COBOL JSON GENERATE and JSON PARSE. With a z/OS Connect API requester, generated artifacts perform the COBOL-to-JSON mapping.

Should a COBOL program retry an HTTP 500 response?

Only when the service contract and local policy allow it. A retry limit, delay, and duplicate-request protection are needed, especially for POST operations.

IBM references

Before the first production call, prove the failure path with a forced timeout and a non-2xx response; the success path is only half of the interface.

New In-feed ads