Case Study 35.1: API Gateway for Legacy DB2 — Modernizing Without Rewriting
Background
Meridian National Bank's core banking system runs on DB2 for z/OS with a 25-year-old COBOL application layer. The system processes 12 million transactions daily and has never missed an SLA. However, the bank is under increasing pressure to deliver mobile banking, partner APIs, and real-time data feeds — capabilities that the COBOL layer was never designed to provide.
The board has approved a modernization initiative with a firm constraint: the core DB2 system must not be rewritten or replaced. It is too stable, too critical, and too well-understood to risk a migration. Instead, the team must build a modern API layer around it.
The Challenge
Build an API gateway that: - Exposes existing DB2 stored procedures as RESTful endpoints - Serves mobile banking, partner, and internal applications - Handles 5,000 concurrent users at peak (lunch hour) - Achieves sub-500ms response times (95th percentile) - Integrates with the bank's existing RACF security infrastructure - Meets PCI-DSS and SOX compliance requirements - Can be deployed and updated without touching the core DB2 system
Architecture Decision
Option 1: Custom Java Application
Build a Spring Boot application with JDBC connections to DB2 z/OS via DB2 Connect.
Pros: Maximum flexibility, familiar technology, full control over JSON formatting. Cons: Requires ongoing development and maintenance. Must implement security mapping manually. Adds network latency (Java server to DB2 across network).
Option 2: z/OS Connect EE (Chosen for Phase 1)
Deploy z/OS Connect EE on the same z/OS LPAR as DB2, mapping stored procedures to REST endpoints.
Pros: Runs on z/OS (same LPAR as DB2, eliminating network latency). Native RACF integration. OpenAPI generation. zIIP-eligible workload reduces MPC costs. IBM-supported product with regulatory pedigree. Cons: Less flexibility in JSON transformation. Learning curve for z/OS Connect tooling. Limited to z/OS deployment.
Option 3: Hybrid (Chosen for Phase 2)
z/OS Connect for core banking operations (transfers, balance inquiries, loan payments). Spring Boot API on cloud for non-transactional operations (statement generation, analytics, notifications).
Phase 1 Implementation: z/OS Connect
Step 1: Identify Target Procedures
The team catalogued 47 stored procedures in the COBOL application and prioritized 12 for REST exposure based on mobile banking requirements:
| Priority | Procedure | Mobile Use Case |
|---|---|---|
| 1 | PROC_GET_BALANCE | Balance check |
| 2 | PROC_TRANSFER_FUNDS | Account transfer |
| 3 | PROC_GET_ACCOUNT_HISTORY | Transaction history |
| 4 | PROC_CUSTOMER_DASHBOARD | Home screen |
| 5 | PROC_PROCESS_LOAN_PAYMENT | Loan payment |
| 6 | PROC_GET_STATEMENTS | Monthly statements |
| 7 | PROC_CHANGE_PIN | PIN management |
| 8 | PROC_SET_ALERTS | Alert preferences |
| 9 | PROC_FREEZE_ACCOUNT | Card freeze |
| 10 | PROC_GET_BRANCH_INFO | Branch locator |
| 11 | PROC_CHECK_DEPOSIT | Mobile deposit |
| 12 | PROC_REPORT_FRAUD | Fraud reporting |
Step 2: Create Service and API Archives
For each procedure, the team created: 1. A service archive mapping procedure parameters to JSON fields 2. An API archive defining the REST endpoint, HTTP method, and URL path
Example for PROC_TRANSFER_FUNDS:
REST endpoint: POST /api/v1/accounts/transfers
Request body → IN parameters: fromAccount, toAccount, amount, description
OUT parameters → Response body: transactionId, statusCode, message
Step 3: Security Configuration
The security architecture layers multiple mechanisms:
- TLS 1.2 for transport encryption
- OAuth2 + JWT for mobile app authentication (issued by the bank's identity provider)
- API Gateway (Kong) for rate limiting, API key management, and request logging
- z/OS Connect maps the JWT subject claim to a RACF user ID
- RACF controls which user ID can EXECUTE which stored procedure
- DB2 authorization provides the final access control layer
Step 4: Performance Tuning
Initial performance testing showed 95th percentile response times of 800ms — above the 500ms target. Investigation revealed three bottlenecks:
-
Connection pool exhaustion. The Liberty data source had a maximum pool size of 10. Under 5,000 concurrent users, connections backed up. Increased to 50.
-
JSON serialization overhead. The PROC_CUSTOMER_DASHBOARD procedure returns three result sets with ~200 total rows. z/OS Connect's JSON transformation for this volume was slow. Optimized by reducing the default result set sizes (added FETCH FIRST N ROWS ONLY to the procedure's cursor declarations).
-
zIIP utilization. The z/OS Connect Liberty JVM was configured as a general-purpose workload. Reconfigured for zIIP eligibility, moving ~70% of CPU consumption off general-purpose engines.
After optimization: 95th percentile response times dropped to 180ms.
Phase 2 Implementation: Hybrid Architecture
Cloud API Layer
A Spring Boot application deployed on Kubernetes handles: - Statement PDF generation (CPU-intensive, runs off-mainframe) - Analytics queries (runs against a DB2 LUW read replica) - Push notification management (integrates with Apple/Google push services) - Partner API management (different rate limits, API keys, and SLAs)
Event Bridge
Kafka Connect with Debezium captures changes from DB2 z/OS and publishes them to Kafka. Downstream consumers include: - Fraud detection (ML model on Kubernetes) - Real-time notification triggers - Analytics pipeline (loads to data warehouse)
Results
| Metric | Before (COBOL only) | After (API Gateway) |
|---|---|---|
| Mobile banking capability | None | Full-featured app |
| Partner integrations | 0 | 14 active partners |
| Average API response time (p95) | N/A | 180ms |
| Core system changes required | N/A | 0 (zero modifications to DB2 or COBOL) |
| Deployment frequency (API layer) | N/A | Weekly |
| Monthly API calls | 0 | 85 million |
| Revenue from partner APIs | $0 | $2.4M annually |
Lessons Learned
- z/OS Connect dramatically reduces time to API. Creating a REST endpoint from an existing stored procedure took 2-3 days, compared to 2-3 weeks for a custom Java implementation.
- The hardest part was security mapping. Mapping OAuth2 tokens through API Gateway through z/OS Connect to RACF to DB2 required collaboration between four different teams.
- Connection pool sizing is critical. Start with the formula: pool_size = peak_concurrent_users / (1000 / avg_query_time_ms). Monitor and adjust based on actual wait times.
- Keep the core system unchanged. The most powerful aspect of this architecture is that DB2 and COBOL were not modified. Twenty-five years of stability were preserved while delivering modern capabilities.
Discussion Questions
- What would you do differently if the core system ran on Db2 for LUW instead of DB2 for z/OS?
- How would you handle an API request that requires data from both DB2 z/OS (transactional) and the analytics DB2 LUW instance?
- The partner API generates $2.4M annually. How would you design the billing system to charge partners per API call?