Chapter 35: Exercises — RESTful APIs and Modern Access Patterns
Exercise 35.1: Db2 REST Service Registration
Objective: Create and consume built-in Db2 REST services (LUW).
- Register a REST service that returns all active accounts for a given customer:
sql -- Write the ADMIN_CMD call to create this service -- The query should accept a customer_id parameter and return -- account_id, account_type, balance, and status - Register a REST service that wraps the
PROC_TRANSFER_FUNDSstored procedure. - Write
curlcommands to invoke both services, including proper authentication headers. - Discuss the limitations you encounter compared to a full REST API framework.
Exercise 35.2: Spring Boot REST API
Objective: Build a REST API endpoint that calls a DB2 stored procedure.
Create a Spring Boot controller with the following endpoints:
| Method | Path | DB2 Backend |
|---|---|---|
| GET | /api/v1/accounts/{id}/statement?year=2025&month=6 | FN_ACCOUNT_STATEMENT table function |
| POST | /api/v1/customers | PROC_ONBOARD_CUSTOMER |
| GET | /api/v1/loans/{id}/schedule | FN_AMORTIZATION_SCHEDULE |
Requirements: - Use HikariCP for connection pooling (configure in application.yml). - Implement input validation using javax.validation annotations. - Return consistent error responses (never expose SQLSTATE or SQLCODE to clients). - Add pagination to the statement endpoint. - Write integration tests using MockMvc.
Exercise 35.3: API Error Handling
Objective: Design a comprehensive error mapping strategy.
Given that PROC_TRANSFER_FUNDS returns these status codes:
- 0: Success
- -1: Invalid input
- -2: Source account error
- -3: Destination account error
- -4: Insufficient funds
- -5: Daily limit exceeded
- Positive values: DB2 SQLCODEs
Create:
1. An ErrorMapper class that maps each status code to an HTTP status code and client-facing error code.
2. A global exception handler that catches DB2 exceptions and returns safe error responses.
3. A test class that verifies every error mapping.
4. A JSON error response format that includes a unique error reference ID for support troubleshooting.
Exercise 35.4: GraphQL Schema Design
Objective: Design a GraphQL schema for a banking domain.
Extend the GraphQL schema from Section 35.5 to include:
- A
creditCardAccounttype with fields for credit limit, available credit, minimum payment due, payment due date, and rewards points. - A
budgetCategorytype that aggregates transactions by category (food, transportation, utilities, etc.) for a given month. - A
queryfieldspendingAnalysisthat accepts a customer ID, start date, and end date, and returns spending by category with month-over-month change percentages. - A
mutationfor setting up automatic loan payments (autopay). - Pagination using cursor-based pagination (not offset-based) for transaction lists.
Write the complete schema additions and explain how each type maps to DB2 queries.
Exercise 35.5: Kafka Connect Configuration
Objective: Configure a Debezium connector for DB2 CDC.
-
Enable CDC on the following tables:
sql ALTER TABLE MERIDIAN.ACCOUNTS DATA CAPTURE CHANGES; ALTER TABLE MERIDIAN.TRANSACTIONS DATA CAPTURE CHANGES; -- What other tables should have CDC enabled for Meridian Bank? -
Write a complete Debezium connector configuration (JSON) that: - Captures changes from ACCOUNTS and TRANSACTIONS only - Routes events to topics named
meridian.events.{table_name}- Excludes sensitive columns (SSN_HASH, SSN_LAST_FOUR) - Configures a dead-letter queue for failed events - Sets appropriate poll intervals for near-real-time processing -
Design a Kafka consumer (pseudocode or Java) that: - Reads from
meridian.events.TRANSACTIONS- Detects large transactions (> $10,000) - Publishes an alert tomeridian.alerts.large-transactions- Implements idempotent processing using a processed-events table
Exercise 35.6: Event-Driven Architecture
Objective: Implement the saga pattern for a multi-step banking operation.
Design a saga for "Open Business Account" that involves these steps: 1. KYC (Know Your Customer) verification — external service call 2. Create customer record in DB2 3. Create business checking account with $10,000 minimum 4. Create linked savings account 5. Set up overdraft protection between the two accounts 6. Send welcome notification
For each step, define: - The action to perform - The compensating action (to undo if a later step fails) - The DB2 table updates involved - The Kafka events published
Write the saga state table DDL and the state transition logic as a stored procedure.
Exercise 35.7: API Security Implementation
Objective: Implement JWT-based authentication for a DB2-backed API.
-
Write a Spring Security filter that: - Extracts the JWT from the Authorization header - Validates the token signature and expiration - Extracts the customer ID claim - Sets the security context with the customer's roles
-
Create an authorization interceptor that ensures: - A customer can only access their own accounts - A teller can access any customer's accounts but cannot modify loan terms - An admin can perform all operations
-
Map JWT roles to DB2 procedure execution: describe how each role's API permissions translate to DB2 EXECUTE privileges.
-
Write a SQL injection test suite that attempts common injection patterns against each endpoint and verifies they are all rejected.
Exercise 35.8: Performance Optimization
Objective: Optimize an API endpoint for high throughput.
You have a /api/v1/accounts/{id}/balance endpoint that is called 10,000 times per minute. Currently it executes:
SELECT BALANCE FROM MERIDIAN.ACCOUNTS WHERE ACCOUNT_ID = ?
Implement three optimization strategies:
-
Response caching with a 5-second TTL using Spring Cache + Redis. Calculate the cache hit ratio if balances change on average every 30 seconds.
-
Connection pool tuning. Given 10,000 requests/minute and an average query execution time of 2ms, calculate the minimum pool size needed. What happens if the pool is too small?
-
Keyset pagination for the transaction history endpoint. Convert this offset-based query to keyset pagination:
sql SELECT * FROM MERIDIAN.TRANSACTIONS WHERE ACCOUNT_ID = ? ORDER BY TRANSACTION_DATE DESC OFFSET 1000 ROWS FETCH NEXT 20 ROWS ONLY;
Exercise 35.9: z/OS Connect Service Design
Objective: Design a z/OS Connect API mapping for existing DB2 procedures.
Given the stored procedure PROC_CUSTOMER_DASHBOARD from Chapter 34 (which returns 3 result sets), design:
- The service archive (.sar) configuration that maps the procedure's parameters.
- The API archive (.aar) configuration that exposes it as
GET /api/v1/customers/{id}/dashboard. - The request mapping (how the URL path parameter maps to the procedure's IN parameter).
- The response mapping (how the three result sets are combined into a single JSON response).
- Security configuration using SAF/RACF integration.
Discuss the challenge of mapping multiple result sets to a JSON response in z/OS Connect.
Exercise 35.10: Full Stack Integration
Objective: Build a complete API-to-database path for a new feature.
Design and implement the "Account Statement Download" feature:
-
DB2 layer: Create a stored procedure or table function that generates a monthly statement with opening balance, all transactions, fees, interest, and closing balance.
-
API layer: Create a REST endpoint
GET /api/v1/accounts/{id}/statements/{year}/{month}that returns the statement as JSON. Add a query parameter?format=pdfthat triggers asynchronous PDF generation. -
Async processing: For PDF generation, return a 202 Accepted with a status URL. Use a Kafka event to trigger the PDF generation worker. Store the result and return it when the client polls the status URL.
-
Caching: Cache generated statements (they are immutable once the month is complete). Use ETags for cache validation.
-
Security: Ensure a customer can only download their own statements. A teller can download any customer's statement but only for auditing purposes (logged).
Document the complete flow from HTTP request to DB2 query and back.