Skip to content

atiqbitstream/IntelliBank-Kafka

Repository files navigation

IntelliBank-Kafka

license NestJS TypeScript Apache Kafka Docker IBM Cloud

Event-driven banking microservices built with NestJS and Apache Kafka, deployed to IBM Cloud Code Engine.

Status: prototype / learning project. The services run and exchange real Kafka events, but several parts are intentionally simplified for demonstration. Account balances live in memory, and the notification service logs messages instead of sending real emails. See the Roadmap for what is and is not implemented.

Table of Contents

About

IntelliBank-Kafka is a small banking platform split into three independent NestJS services that talk to each other through Apache Kafka topics instead of direct HTTP calls. It shows how an event-driven design decouples services so that creating a customer, processing a transaction, and sending a notification can each scale and fail on their own.

The project is a NestJS monorepo. Each service is its own application with its own entry point, Dockerfile, and Kafka client. The services connect to a managed Kafka cluster (IBM Event Streams) over SASL/SSL, and a GitHub Actions workflow builds the Docker images and deploys them to IBM Cloud Code Engine.

The repository name uses "IntelliBank" as a brand. The domain is banking-style customer and transaction handling; the focus of the code is the Kafka event flow rather than real banking logic.

Features

  • Three decoupled microservices: customer-service, transaction-service, and notification-service.
  • Asynchronous communication over Apache Kafka using kafkajs through @nestjs/microservices.
  • A shared KafkaConnectionUtils helper that standardizes the Kafka client config (SASL/SSL, timeouts, retries, idempotent producer) across all services.
  • Broker list parsing that accepts either a JSON array or a comma-separated string from one environment variable.
  • Transaction processing with sender/recipient checks and insufficient-funds handling, emitting success, failure, and error events.
  • Notification handlers that react to customer and transaction events.
  • One Dockerfile per service and a GitHub Actions pipeline that deploys to IBM Cloud Code Engine.

Tech Stack

Layer Technology
Language TypeScript
Framework NestJS 10 (monorepo)
Messaging Apache Kafka via kafkajs and @nestjs/microservices
HTTP Express (@nestjs/platform-express)
Package manager pnpm
Containers Docker (node:18-alpine)
Cloud IBM Cloud Code Engine and IBM Event Streams
Container registry IBM Container Registry (au.icr.io)
CI/CD GitHub Actions
Testing Jest

Architecture

Each service exposes an HTTP endpoint and also runs as a Kafka microservice. Producers emit events to topics; consumers subscribe with @MessagePattern. The notification service is a pure consumer.

flowchart LR
    Client[HTTP Client]

    subgraph Services
        CS[customer-service<br/>port 3000]
        TS[transaction-service<br/>port 3002]
        NS[notification-service<br/>port 3001]
    end

    Kafka[(Apache Kafka<br/>IBM Event Streams)]

    Client -->|POST /customer| CS
    Client -->|POST /transactions| TS

    CS -->|emit customer.created| Kafka
    TS -->|emit transaction.requested| Kafka
    Kafka -->|transaction.requested| TS
    TS -->|emit transaction.processed / failed / error| Kafka

    Kafka -->|customer.created| NS
    Kafka -->|transaction.processed| NS
Loading

Topics used in the code:

Topic Produced by Consumed by
customer.created customer-service notification-service
transaction.requested transaction-service (HTTP) transaction-service (processor)
transaction.processed transaction-service notification-service
transaction.failed transaction-service (emitted, not yet consumed)
transaction.error transaction-service (emitted, not yet consumed)

Getting Started

Prerequisites

  • Node.js 18 or newer
  • pnpm
  • Access to a Kafka cluster. The code is set up for IBM Event Streams with SASL/SSL, so you need broker addresses plus a user and password.
node --version
pnpm --version

Installation

git clone https://github.com/atiqbitstream/IntelliBank-Kafka.git
cd IntelliBank-Kafka
pnpm install

Configure environment

The services read Kafka settings from environment variables (see Configuration). Set them in your shell or a .env file before starting a service.

export EVENT_STREAMS_KAFKA_BROKERS_SASL='["broker-1:9093","broker-2:9093"]'
export EVENT_STREAMS_USER='your-kafka-user'
export EVENT_STREAMS_PASSWORD='your-kafka-password'

Run a service locally

This is a NestJS monorepo, so you start one service at a time by name.

# Customer service on port 3000
pnpm exec nest start customer-service

# Transaction service on port 3002
pnpm exec nest start transaction-service

# Notification service on port 3001
pnpm exec nest start notification-service

Add --watch for hot reload during development, for example pnpm exec nest start customer-service --watch.

Try the endpoints

Create a customer (emits customer.created):

curl -X POST http://localhost:3000/customer \
  -H "Content-Type: application/json" \
  -d '{"id":"cust-001","name":"John Doe","email":"john@example.com"}'

Initiate a transaction (emits transaction.requested, then processed/failed/error):

curl -X POST http://localhost:3002/transactions \
  -H "Content-Type: application/json" \
  -d '{"from":"cust-001","to":"cust-002","amount":100,"transactionId":"txn-123"}'

The notification service has no HTTP endpoint to call. Watch its logs to see it react to the events above. The transaction service seeds two demo accounts in memory, cust-001 with 1000 and cust-002 with 500.

Build with Docker

Each service has its own Dockerfile.

docker build -t customer-service -f Dockerfile.customer-service .
docker build -t transaction-service -f Dockerfile.transaction-service .
docker build -t notification-service -f Dockerfile.notification-service .

Deploy

Pushing to the master branch triggers .github/workflows/deploy.yml, which logs in to IBM Cloud, builds and pushes each image to au.icr.io, and updates the matching Code Engine applications. The workflow expects an IBM_CLOUD_API_KEY repository secret and existing Code Engine applications named customer-service, transaction-service, and notification-service.

Project Structure

.
├── apps/
│   ├── customer-service/
│   │   ├── src/                      # controller, service, module, main
│   │   └── kafka-connection.utils.ts # shared Kafka client config
│   ├── transaction-service/
│   │   ├── src/                      # transaction processing + events
│   │   └── kafka-connection.utils.ts
│   └── notification-service/
│       ├── src/                      # event consumers
│       └── kafka-connection.utils.ts
├── Dockerfile.customer-service
├── Dockerfile.transaction-service
├── Dockerfile.notification-service
├── .github/workflows/deploy.yml      # CI/CD to IBM Cloud Code Engine
├── nest-cli.json                     # monorepo project definitions
└── package.json

Configuration

All services read the same Kafka variables through KafkaConnectionUtils.

Variable Description Default
EVENT_STREAMS_KAFKA_BROKERS_SASL Kafka broker list, as a JSON array or a comma-separated string none (required; empty list logs an error)
EVENT_STREAMS_USER SASL username for the Kafka cluster empty string
EVENT_STREAMS_PASSWORD SASL password for the Kafka cluster empty string
PORT HTTP port for the service 3000 (customer), 3001 (notification), 3002 (transaction)

The Kafka client always uses SSL with the SASL plain mechanism and an idempotent producer with three retries.

Roadmap

  • Persist customers and account balances in a database instead of in-memory maps.
  • Send real notifications (email or SMS) from the notification service instead of logging.
  • Add consumers for transaction.failed and transaction.error events.
  • Add input validation and DTOs on the HTTP endpoints.
  • Provide a local docker-compose with a Kafka broker for offline development.
  • Expand unit and end-to-end test coverage.

Contributing

Contributions are welcome. Open an issue to discuss a change, then send a pull request. Please run pnpm lint and pnpm test before submitting.

License

Distributed under the MIT License. See LICENSE.

About

Event-driven banking microservices built with NestJS, TypeScript, and Apache Kafka. Three decoupled services (customer, transaction, notification) communicate over Kafka topics, run in Docker, and deploy to IBM Cloud Code Engine and IBM Event Streams via GitHub Actions.

Topics

Resources

License

Stars

0 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors