Backend-for-Frontend API powering the customer mobile banking app.
The BFF (Backend-for-Frontend) API provides a thin, customer-facing JSON layer over the GoBank simulation. It is designed to serve the mobile banking app UI and sits between the customer’s device and the internal bank systems.
In production this would be a separate service with its own authentication, rate limiting, and audit logging. In the demo it runs in-process alongside the admin dashboard.
| Base path | /api/ |
| Format | JSON (UTF-8) |
| Auth | None (demo) — production would use OAuth 2.0 / Open Banking |
| Phone UI | /app/ — server-rendered HTML consuming the same service methods |
POST /app/login, simulated)GET /api/customer/{id}/accounts — net balance, all productsGET /api/customer/{id}/product/{idx} — sort code, account no., rate, balanceGET /api/customer/{id}/product/{idx}/transactions — per-product activityList all customers (for login / account selection). Returns ID and name only.
Response: 200 OK
[
{ "id": "C-00001", "name": "Alice Smith" },
{ "id": "C-00002", "name": "Bob Jones" }
]
Holding page data: all accounts for a customer with aggregate balances. This is the primary endpoint loaded after login.
| Param | Type | Description |
|---|---|---|
{id} | path | Customer ID (e.g. C-00001) |
Response: 200 OK / 404 Not Found
{
"customer_id": "C-00001",
"customer_name": "Alice Smith",
"accounts": [
{
"product_name": "Easy Access Saver",
"family": "Savings",
"rate": 0.015,
"balance": 12500.00,
"interest": 47.26
},
{
"product_name": "Personal Loan",
"family": "Lending",
"rate": 0.049,
"balance": 5000.00,
"interest": 61.50
}
],
"total_savings": 12500.00,
"total_lending": 5000.00
}
Detail for a single product/account. Includes sort code, account number, and opening date — the information a customer needs for payments and direct debits.
| Param | Type | Description |
|---|---|---|
{id} | path | Customer ID |
{idx} | path | Account index (0-based position in the accounts array) |
Response: 200 OK / 404 Not Found
{
"customer_id": "C-00001",
"customer_name": "Alice Smith",
"account_index": 0,
"product_name": "Easy Access Saver",
"family": "Savings",
"rate": 0.015,
"balance": 12500.00,
"interest": 47.26,
"sort_code": "30-90-01",
"account_num": "12345678",
"open_date": "2020-01-15"
}
Transaction history for a single product. Paginated, newest first. Use this to show activity on the product detail screen.
| Param | Type | Description |
|---|---|---|
{id} | path | Customer ID |
{idx} | path | Account index |
page | query | Page number (1-based, default 1) |
Response: 200 OK
{
"customer_id": "C-00001",
"page": 1,
"total_count": 42,
"per_page": 20,
"entries": [
{
"id": 1234,
"date": "2021-06-15",
"product_name": "Easy Access Saver",
"type": "Interest",
"amount": 0.51,
"balance": 12500.51,
"reference": "INT-001234"
}
]
}
Transaction history across all products for a customer. Same pagination and response shape as the per-product endpoint.
| Param | Type | Description |
|---|---|---|
{id} | path | Customer ID |
page | query | Page number (1-based, default 1) |
The /app/ routes serve the same data as the BFF API, rendered as server-side HTML inside a phone frame. Each screen maps to an API call:
| Screen | Route | API Equivalent |
|---|---|---|
| Login | GET /app/ | GET /api/customers |
| Login (submit) | POST /app/login | — (redirect only) |
| Holding page | GET /app/customer/{id} | GET /api/customer/{id}/accounts |
| Product detail | GET /app/customer/{id}/product/{idx} | GET /api/customer/{id}/product/{idx} |
| All activity | GET /app/customer/{id}/transactions | GET /api/customer/{id}/transactions |
| Concern | Demo | Production |
|---|---|---|
| Authentication | None — customer selected from list | OAuth 2.0 / Open Banking OIDC; PIN verified against HSM |
| Authorisation | Any customer can view any account | Token-scoped to authenticated customer; consent model for third-party access |
| Rate limiting | None | Per-customer rate limits; DDoS protection |
| Audit | None | Every API call logged with customer ID, IP, timestamp |
| PII | Name returned in JSON | PII minimised; name returned only where needed; GDPR-compliant retention |
| TLS | HTTP (localhost) | TLS 1.3 required; certificate pinning on mobile app |
| Versioning | None | /api/v1/ prefix; deprecation policy |