A distributed database system with a Go API Gateway coordinating three polyglot worker shards.
This project implements a sharded, distributed database where:
- A Go Master node acts as an API gateway — it validates requests, routes shards, and coordinates scatter/gather reads and MapReduce operations.
- Three Worker nodes (Go, Python, Node.js) each own a physical SQL Server database shard and execute all actual SQL.
- Clients talk only to the Master on port
8080. Workers reject direct access with401 Unauthorized.
Client / Postman / GUI
│
▼
┌─────────────────────────────┐
│ Master API Gateway (Go) │ :8080
│ • Request validation │
│ • Shard routing │
│ • Scatter/gather reads │
│ • MapReduce coordination │
│ • Health monitoring │
└──────────┬──────────────────┘
│ X-Master-Token
┌─────┼──────────┐
▼ ▼ ▼
Worker Worker Worker
Go Python Node.js
:8081 :8082 :8083
SchoolDBGO SchoolDBPY SchoolDBNODE
| Request Type | Shard Key Source | Routing |
|---|---|---|
| INSERT | shard_key → student_id / user_id → row hash |
One worker |
| SELECT (with key) | shard_key or student_id = X in condition |
One worker |
| SELECT (no key) | — | Scatter/gather all workers |
| UPDATE | shard_key required |
One worker |
| DELETE | shard_key required |
One worker |
| Logical Name | Worker | Physical DB |
|---|---|---|
SchoolDB |
Go | SchoolDBGO |
SchoolDB |
Python | SchoolDBPY |
SchoolDB |
Node.js | SchoolDBNODE |
distributed-db/
├── master/ # Go API Gateway — port 8080
│ ├── main.go # HTTP server, routes, CORS
│ ├── handlers.go # All HTTP handler functions
│ ├── replication.go # Shard routing, fan-out, MapReduce
│ └── go.mod
│
├── slave-go/ # Go worker shard — port 8081 — suffix GO
│ ├── main.go
│ ├── handlers.go
│ ├── db.go # SQL Server connection + SwitchDB
│ └── go.mod
│
├── slave-python/ # Python Flask worker shard — port 8082 — suffix PY
│ ├── app.py
│ └── requirements.txt
│
├── slave-node/ # Node.js Express worker shard — port 8083 — suffix NODE
│ ├── server.js
│ └── package.json
│
└── docs/
├── postman-guide.md
└── Distributed_DB_Postman_Collection.json
| Requirement | Version |
|---|---|
| Go | 1.21+ |
| Python | 3.9+ |
| Node.js | 18+ |
| SQL Server | Any with Windows Authentication |
| ODBC Driver | 17 for SQL Server |
Install ODBC Driver 17: Microsoft Download
Open four separate terminals, one per service.
cd master
go run .
# Listening on :8080cd slave-go
go run .
# Listening on :8081cd slave-python
pip install -r requirements.txt
python app.py
# Listening on :8082cd slave-node
npm install
node server.js
# Listening on :8083cd master
$env:MASTER_PORT="8084"
$env:MASTER_ROLE="backup"
go run .Import the Postman collection and follow the step-by-step guide:
- Import
docs/Distributed_DB_Postman_Collection.jsoninto Postman. - Follow
docs/postman-guide.mdto demonstrate all features.
# Create databases on all shards
curl -X POST http://localhost:8080/create-db \
-H "Content-Type: application/json" \
-d '{"db_name": "SchoolDB"}'
# Create the table schema on all shards
curl -X POST http://localhost:8080/create-table \
-H "Content-Type: application/json" \
-d '{
"db_name": "SchoolDB",
"table": "Students",
"columns": {
"student_id": "INT",
"name": "VARCHAR(100)",
"grade": "VARCHAR(5)"
}
}'
# Insert — routed to one shard
curl -X POST http://localhost:8080/insert \
-H "Content-Type: application/json" \
-d '{
"db_name": "SchoolDB",
"table": "Students",
"shard_key": "1001",
"data": {"student_id": "1001", "name": "Ali", "grade": "A"}
}'
# Select — single shard (key provided)
curl -X POST http://localhost:8080/select \
-H "Content-Type: application/json" \
-d '{
"db_name": "SchoolDB",
"table": "Students",
"shard_key": "1001",
"condition": "student_id = 1001"
}'
# Select — scatter/gather all shards (no key)
curl -X POST http://localhost:8080/select \
-H "Content-Type: application/json" \
-d '{"db_name": "SchoolDB", "table": "Students"}'
# MapReduce count
curl -X POST http://localhost:8080/map-reduce-count \
-H "Content-Type: application/json" \
-d '{"db_name": "SchoolDB", "table": "Students"}'All requests go to http://localhost:8080.
| Method | Endpoint | Body fields |
|---|---|---|
POST |
/create-db |
db_name |
POST |
/drop-db |
db_name |
POST |
/create-table |
db_name, table, columns (object) |
POST |
/delete-table |
db_name, table |
| Method | Endpoint | Body fields | Notes |
|---|---|---|---|
POST |
/insert |
db_name, table, data, shard_key? |
Routed to one shard |
POST |
/select |
db_name, table, condition?, shard_key? |
One shard or scatter/gather |
POST |
/update |
db_name, table, set, condition, shard_key? |
Requires shard key |
POST |
/delete |
db_name, table, condition, shard_key? |
Requires shard key |
| Method | Endpoint | Description |
|---|---|---|
GET |
/metadata |
Master role, worker list, routing info |
GET |
/health |
Gateway + all worker health |
POST |
/map-reduce-count |
Count rows across all shards |
POST |
/security-check |
Prove workers reject tokenless requests |
External Client ──► Master (port 8080)
│
│ adds X-Master-Token: master-secret-token-2025
▼
Worker Nodes (8081–8083)
- Workers expose no public interface. Every non-health endpoint checks
X-Master-Token. - Missing or wrong token →
401 Unauthorized. - The GUI/Postman never needs to know the token — the Master injects it on forwarding.
| Feature | How it works |
|---|---|
| Sharding | FNV-1a hash of shard key % 3 selects the worker |
| Scatter/Gather | SELECT without key fans out to all 3 workers concurrently |
| MapReduce | Workers map (return rows), Master reduces (sums counts) |
| API Gateway security | Workers reject all requests without X-Master-Token |
| Request validation | Master rejects non-POST, missing fields, unsafe updates |
| Health monitoring | Master polls workers concurrently and reports status |
| Master failover | Backup master on :8084 — stateless, same routing config |
| Polyglot workers | Go · Python Flask · Node.js Express — same REST contract |
Because the Master stores only routing metadata (no application data), failover is seamless:
- Start backup master:
MASTER_PORT=8084 MASTER_ROLE=backup go run . - Kill primary master (
:8080). - Change your Postman
baseUrltohttp://localhost:8084. - All operations continue — workers are unchanged.
MIT — see LICENSE.