Skip to content
PYD ENTERPRISES

Migration guide

CICS to REST: turning COMMAREAs and BMS maps into OpenAPI 3.1

A CICS transaction already is an API: a COMMAREA in, a COMMAREA or a screen out. This guide shows how to recover that contract and its hidden state before you put REST in front of it or replace it.

CICSREST / OpenAPI 3.1
DIFFICULTY
High
OUTPUT
OpenAPI / YAML
SYNTAX TRAPS
5 covered
WORKFLOW
6 steps

By Pranav Kulkarni, Head of Language Engineering · Updated 15 Oct 2026

Technical syntax challenges

Where CICS migrations go wrong.

01

Pseudo-conversational state in the COMMAREA

Between screens the task ends with EXEC CICS RETURN TRANSID('LN01') COMMAREA(WS-COMM). State lives in the COMMAREA (or a TS queue) and is checked through EIBCALEN on re-entry. A REST design must decide which of those fields become request parameters and which become server-side resources.

02

BMS maps mix presentation and validation

Field attributes in the BMS macro (ATTRB=(UNPROT,NUM), LENGTH=9) and the symbolic map's L, F and A suffix fields carry validation rules that the program never repeats. Those constraints belong in the request schema, not in a React form alone.

03

LINK and XCTL chains

EXEC CICS LINK PROGRAM('LNVAL01') COMMAREA(...) returns control; XCTL does not. The operation boundary of a REST endpoint often spans three programs, and the COMMAREA layout of each callee becomes an internal contract.

04

EIBAID and function key semantics

PF3 means exit, PF7 and PF8 page, ENTER submits. Paging through EIBAID with a stored key in the COMMAREA is a cursor-based pagination contract in disguise.

05

HANDLE CONDITION and RESP codes

Older programs use EXEC CICS HANDLE CONDITION NOTFND(9100-NOT-FOUND), newer ones test RESP after each command. Both define error responses (404, 409) that should appear in the OpenAPI document with the source lines that raise them.

Extraction workflow

6 steps from source to signed-off spec.

The sequence a PYD ENTERPRISES Discovery Scan runs for this stack. Every output links back to source file and line range.

  1. 1

    Collect programs, BMS mapsets and CSD definitions

    Export the COBOL programs, BMS macro source, symbolic map copybooks and the CSD transaction and program definitions so transaction IDs resolve to programs.

  2. 2

    Resolve COMMAREA layouts per program

    PYD ENTERPRISES computes the DFHCOMMAREA layout in the LINKAGE SECTION of each program, including REDEFINES used to switch between request and response shapes.

  3. 3

    Trace the pseudo-conversational state machine

    Each RETURN TRANSID with a COMMAREA becomes a state transition. The extractor records which fields are set before return and read after re-entry.

  4. 4

    Follow LINK and XCTL into one operation graph

    Called programs are merged into the operation boundary, with their COMMAREAs recorded as internal schemas so the API team sees every hop.

  5. 5

    Lift BMS attributes into schema constraints

    NUM, LENGTH, PICIN and required-field checks in the program become JSON Schema constraints on the request body.

  6. 6

    Synthesize OpenAPI 3.1 and review

    Operations, request and response schemas and error codes are exported with x-pyd-source links. Architects review naming and resource boundaries before publishing.

Legacy in, specification out

The source, and what PYD ENTERPRISES extracts from it.

Left: the CICS construct as it sits in production. Right: the reviewed artifact your REST / OpenAPI 3.1 engineers build against. PYD ENTERPRISES produces the spec and the tests; your team writes the service.

LEGACY SOURCE

LNINQ01.cblCOBOL
1 LINKAGE SECTION.
2 01 DFHCOMMAREA.
3 05 CA-LOAN-ID PIC X(10).
4 05 CA-FUNCTION PIC X(01).
5 88 CA-INQUIRY VALUE 'I'.
6 05 CA-PRIN-BAL PIC S9(9)V99 COMP-3.
7 05 CA-NEXT-DUE-DATE PIC 9(08).
8 05 CA-RETURN-CODE PIC X(02).
9 PROCEDURE DIVISION.
10 IF EIBCALEN = 0
11 PERFORM 1000-SEND-EMPTY-MAP
12 ELSE
13 EXEC CICS READ FILE('LNMAST')
14 INTO(LN-MASTER-REC)
15 RIDFLD(CA-LOAN-ID)
16 RESP(WS-RESP)
17 END-EXEC
18 IF WS-RESP = DFHRESP(NOTFND)
19 MOVE 'NF' TO CA-RETURN-CODE
20 END-IF
21 END-IF.

EXTRACTED ARTIFACT

loan-inquiry.openapi.yamlYAML
1openapi: 3.1.0
2info:
3 title: Loan inquiry (from LNINQ01)
4 version: 1.0.0
5paths:
6 /loans/{loanId}:
7 get:
8 operationId: getLoan
9 x-pyd-source: LNINQ01.cbl:42-61
10 parameters:
11 - name: loanId
12 in: path
13 required: true
14 schema: { type: string, maxLength: 10 }
15 responses:
16 "200":
17 content:
18 application/json:
19 schema: { $ref: "#/components/schemas/LoanSummary" }
20 "404":
21 description: VSAM READ RESP NOTFND, CA-RETURN-CODE 'NF'
22components:
23 schemas:
24 LoanSummary:
25 type: object
26 properties:
27 principalBalance: { type: string, pattern: "^-?\\d{1,9}\\.\\d{2}$" }
28 nextDueDate: { type: string, format: date }

Architectural best practices

Build the REST / OpenAPI 3.1 side to the spec, not to the old shape.

  • Design resources around the business entity the transaction reads or updates, not around the transaction ID.
  • Keep pseudo-conversational state on the server only where the legacy flow needs it for integrity (for example a two-step funds hold); otherwise make requests stateless.
  • Carry BMS field constraints into JSON Schema so web and API clients enforce the same limits the 3270 screen did.
  • Map each RESP condition the program handles to a documented HTTP status, and flag unhandled conditions that end in an abend.
  • Publish the extracted contract first and let the CICS program serve it through a facade while the replacement service is built behind it.

Two routes from the same contract

Some teams expose existing CICS programs as REST through z/OS Connect or a CICS web service and replace them later; others build the replacement service directly. Both need the same artifact first: an accurate OpenAPI document describing what the transaction accepts, returns and refuses.

PYD ENTERPRISES produces that document from the source and links every property and error to the lines it came from. It does not generate the facade or the replacement service. Your architects decide resource names and boundaries during review, with the COMMAREA layout and the extracted state machine side by side.

Reading EIBCALEN correctly

EIBCALEN = 0 means the transaction started without a COMMAREA: the first screen. Everything after that branch is the stateful part of the conversation. The extractor treats the first-entry branch as a separate operation (often a GET that returns an empty form or defaults) and the re-entry branches as the real business operations. Getting this split wrong is the usual reason hand-written OpenAPI documents for CICS have operations that cannot be called in isolation.

FAQ

CICS to REST / OpenAPI 3.1 questions

Do we need a running CICS region for extraction?

No. Extraction is static: program source, BMS maps, symbolic map copybooks and CSD definitions are enough. A region is useful later to run the generated equivalence fixtures against the live transaction.

Can PYD ENTERPRISES handle channels and containers instead of COMMAREAs?

Yes. GET CONTAINER and PUT CONTAINER calls are traced like COMMAREA fields, with each container treated as a named part of the request or response schema.

What about TS and TD queues used for state?

WRITEQ TS and READQ TS calls are recorded as state reads and writes in the conversation graph, so architects can see which state outlives a single request and decide where it lives in the target design.

Get the spec for your CICS estate.

Request a codebase scan and review extracted rules, contracts and fixtures for your own CICS estate, inside your VPC.