A production-grade, event-driven stock trading platform built with a Java Spring Boot microservices architecture. The system handles real-time order placement, order matching, trade execution, market-data streaming, and user portfolio management β all coordinated through Apache Kafka and backed by PostgreSQL.
- Architecture Overview
- Microservices
- Technology Stack
- Getting Started
- API Reference
- Kafka Event Flow
- Security
- Project Structure
- Contributing
ββββββββββββββββββββββββββββββ
β API Gateway β
β (Port 8080 Β· JWT Filter) β
ββββββββββββββ¬ββββββββββββββββ
β routes requests
βββββββββββββββββββββββββββΌβββββββββββββββββββββββββββ
βΌ βΌ βΌ
ββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββββββ
β User Service β β Order Service β β Market Data Service β
β (Port 8081) β β (Port 8082) β β (Port 8085) β
ββββββββββββββββ ββββββββββ¬ββββββββββ βββββββββββββββββββββββ
β Kafka: orders-topic
βΌ
ββββββββββββββββββββββββ
β Matching Engine β
β (Port 8083) β
ββββββββββββ¬ββββββββββββ
β Kafka: trades-topic
βΌ
ββββββββββββββββββββββββ
β Trade Service β
β (Port 8084) β
ββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Eureka Discovery Server (Port 8761) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Infrastructure: Apache Kafka Β· PostgreSQL (Supabase) Β· Redis
| Service | Port | Responsibility |
|---|---|---|
| Eureka Server | 8761 |
Service discovery & registry |
| API Gateway | 8080 |
Single entry point, JWT validation, routing |
| User Service | 8081 |
Registration, login, JWT issuance, portfolio |
| Order Service | 8082 |
Order placement, validation, Kafka publishing |
| Matching Engine | 8083 |
Order book, buy/sell matching, trade generation |
| Trade Service | 8084 |
Trade event consumption, history persistence |
| Market Data Service | 8085 |
Real-time price feeds, WebSocket streaming |
| Category | Technology |
|---|---|
| Language | Java 17 |
| Framework | Spring Boot 3.x |
| Service Discovery | Spring Cloud Netflix Eureka |
| API Gateway | Spring Cloud Gateway MVC |
| Messaging | Apache Kafka (Confluent 7.5) |
| Database | PostgreSQL 15 (Supabase) |
| Caching | Redis 7.2 |
| Security | Spring Security + JWT (JJWT) |
| ORM | Spring Data JPA / Hibernate |
| Build Tool | Maven (Maven Wrapper included) |
| Containerisation | Docker + Docker Compose |
| Tool | Version |
|---|---|
| Java JDK | 17+ |
| Maven | 3.9+ (or use included mvnw) |
| Docker & Docker Compose | Latest |
| Git | Any |
Start Kafka, Zookeeper, PostgreSQL and Redis via Docker Compose:
docker-compose up -dThis spins up:
- Zookeeper on port
2181 - Kafka on port
9092 - PostgreSQL on port
5432(db:tradingdb, user:postgres) - Redis on port
6379
Every service ships with an application.properties.example template located at:
<service>/src/main/resources/application.properties.example
Copy and populate the template for each service:
# Example for user-service
cp user-service/src/main/resources/application.properties.example \
user-service/src/main/resources/application.propertiesThen edit the file and replace the placeholder values:
| Placeholder | Description |
|---|---|
<DB_HOST> |
PostgreSQL hostname (e.g. localhost or Supabase host) |
<DB_NAME> |
Database name (e.g. postgres) |
<DB_USER> |
Database username |
<DB_PASSWORD> |
Database password |
<YOUR_JWT_SECRET_MIN_32_CHARS> |
A random 32+ character secret key |
β οΈ Never commitapplication.propertiesβ it is excluded by.gitignore.
Start services in order (each in its own terminal):
# 1. Eureka Discovery Server (must start first)
cd eureka-server && ./mvnw clean spring-boot:run
# 2. API Gateway
cd api-gateway && ./mvnw clean spring-boot:run
# 3. User Service
cd user-service && ./mvnw clean spring-boot:run
# 4. Order Service
cd order-service && ./mvnw clean spring-boot:run
# 5. Matching Engine
cd matching-engine && ./mvnw clean spring-boot:run
# 6. Trade Service
cd trade-service && ./mvnw clean spring-boot:run
# 7. Market Data Service
cd market-data-service && ./mvnw clean spring-boot:runVerify everything is up:
- Eureka Dashboard β http://localhost:8761
- All 6 services should appear as
UPin the registry.
All requests go through the API Gateway at http://localhost:8080.
| Method | Endpoint | Auth | Description |
|---|---|---|---|
POST |
/api/users/register |
β Public | Register a new user |
POST |
/api/users/login |
β Public | Login & receive JWT token |
GET |
/api/users/portfolio |
β Bearer | View user portfolio |
Register
POST /api/users/register
{
"username": "akhil",
"email": "akhil@example.com",
"password": "secret123"
}Login
POST /api/users/login
{
"email": "akhil@example.com",
"password": "secret123"
}
// Response: { "token": "eyJhbGci..." }| Method | Endpoint | Auth | Description |
|---|---|---|---|
POST |
/api/orders |
β Bearer | Place a new order |
GET |
/api/orders/{userId} |
β Bearer | Get orders for a user |
Place Order
POST /api/orders
Authorization: Bearer <token>
{
"userId": 1,
"symbol": "AAPL",
"quantity": 10,
"price": 185.50,
"orderType": "LIMIT",
"orderSide": "BUY"
}Order types: LIMIT, MARKET
Order sides: BUY, SELL
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET |
/api/trades/{userId} |
β Bearer | Get trade history for a user |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET |
/api/market/{symbol} |
β Public | Get latest price for a symbol |
WS |
/ws/market |
β Public | WebSocket real-time price feed |
Order Service
β
β orders-topic (OrderEventDTO)
βΌ
Matching Engine
β β Matches BUY/SELL orders from the in-memory order book
β
β trades-topic (TradeEventDTO)
βΌ
Trade Service
β β Persists executed trades to PostgreSQL
β β Updates user portfolios
| Topic | Producer | Consumer | Payload |
|---|---|---|---|
orders-topic |
Order Service | Matching Engine | OrderEventDTO |
trades-topic |
Matching Engine | Trade Service | TradeEventDTO |
- JWT Authentication is enforced at the API Gateway level via
JwtAuthFilter. - Tokens are issued by the User Service on successful login.
- The JWT secret must be identical in
user-serviceandapi-gatewayconfigs. - Public endpoints (no token required):
POST /api/users/registerPOST /api/users/loginGET /api/market/**- WebSocket
/ws
trading-engine/
βββ docker-compose.yml # Infrastructure (Kafka, PG, Redis)
βββ .gitignore # Protects secrets & build artifacts
β
βββ eureka-server/ # Service registry
βββ api-gateway/ # JWT auth + routing
β βββ src/main/
β βββ java/.../filter/JwtAuthFilter.java
β βββ resources/application.properties.example
β
βββ user-service/ # Auth, registration, portfolio
β βββ src/main/
β βββ java/.../model/User.java
β βββ resources/application.properties.example
β
βββ order-service/ # Order placement & Kafka publishing
β βββ src/main/
β βββ java/.../dto/OrderRequestDTO.java
β βββ resources/application.properties.example
β
βββ matching-engine/ # Order book & trade matching
β βββ src/main/
β βββ resources/application.properties.example
β
βββ trade-service/ # Trade event consumer & history
β βββ src/main/
β βββ resources/application.properties.example
β
βββ market-data-service/ # Price feeds & WebSocket
βββ src/main/
βββ resources/application.properties.example
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Copy and configure all
application.properties.examplefiles β do not commit real credentials - Commit your changes:
git commit -m "feat: add my feature" - Push and open a Pull Request
This project is open-source and available under the MIT License.