A modular C++ backend system inspired by Uberβs architecture. This project simulates a microservices environment to manage users, rides, and locations, using secure, scalable, and modern design patterns.
- π§© Microservice Architecture
- Independent services:
UserManager,RideManager, andLocationManager
- Independent services:
- πΎ Multi-DB Support: MySQL, PostgreSQL, SQLite (per service)
- π§΅ Thread Pool: Asynchronous background task execution
- πͺ΅ Color-Coded Logger: Singleton-based centralized logging
- π JWT Authentication: Secure login/session using JSON Web Tokens
- π¬ Message Brokers:
- Kafka: For inter-service events (
user_created, etc.) - RabbitMQ: For async job/event delegation with an in-memory fallback to simplify local testing
- Kafka: For inter-service events (
- π¦ Shared Libraries via
cpp_base - βοΈ Secure Configuration: Via
.envfile + environment variables - π³ Dockerized: Each microservice has its own Dockerfile & entrypoint
- π CI/CD Ready: GitHub Actions build and push Docker images
- π gRPC Services: LocationManager boots its own gRPC endpoint alongside HTTP handlers
- π Ride Settlement Runbook: End-to-end booking β wallet flow captured in
docs/ride_lifecycle_settlement.md
- Language: C++17 / C++20
- Databases: MySQL, PostgreSQL, SQLite
- Message Brokers: Apache Kafka, RabbitMQ
- Networking: gRPC + Protobuf
- Build: CMake + Conan
- Containerization: Docker + docker-compose
- CI/CD: GitHub Actions
uber-backend/
βββ UserManager/ # Handles users + JWT auth
β βββ include/ # Headers
β βββ src/ # Source
β βββ sql_scripts/ # SQL init files
β
βββ RideManager/ # Handles ride matching and booking
βββ LocationManager/ # Geolocation services (H3-based)
β
βββ sharedUtils/ # Logger, thread pool, config loader
βββ sharedResources/ # Shared gRPC, Kafka, RabbitMQ, DB
βββ proto/ # gRPC proto definitions
βββ docker/ # Dockerfiles per service
β
βββ entrypointUserManager.sh # Entrypoint: UserManager
βββ entrypointRideManager.sh # Entrypoint: RideManager
βββ entrypointLocationManager.sh # Entrypoint: LocationManager
β
βββ .env # Environment variables
βββ docker-compose.yml # Multi-service orchestration
βββ CMakeLists.txt
βββ conanfile.py
βββ README.md
Each microservice follows this initialization flow:
-
Database Initialization
Initializes a dedicated SQL database for the service. This stores all persistent data relevant to the service domain. -
HTTP Handler Launch
Sets up HTTP servers and clients, routes incoming requests to proper controllers, and manages outgoing requests. -
Kafka Handler Activation
Initializes Kafka producers and consumers for event-driven communication between microservices.
-
ποΈ Database
Dedicated storage per service using MySQL, PostgreSQL, or SQLite. -
π HTTP Handler
Manages HTTP servers and clients. Routes requests to appropriate handlers. -
π₯ HTTP Server
Listens for external or internal HTTP requests and serves responses based on API logic. -
π€ HTTP Client
Sends HTTP requests to other microservices to fetch or send data. -
π§ Kafka Handler
Coordinates Kafka producer and consumer setup within the service. -
π© Kafka Consumer
Subscribes to topics and listens for inter-service messages. Integrates incoming data into the service's workflow. -
π¨ Kafka Producer
Publishes events/messages to Kafka topics for other microservices to consume.
Purpose: Manage all user-related operations
Responsibilities:
- Handle user registration and login
- Manage user profiles (name, email, phone)
- Generate JWT tokens and hash passwords (bcrypt/Argon2)
- Publish events to Kafka/RabbitMQ (e.g., user signup)
- Expose HTTP endpoints:
/register/login/profile
Purpose: Handle ride requests, assignments, and tracking
Responsibilities:
- Accept and manage ride requests
- Assign drivers based on proximity and availability
- Track ride status (
requested β accepted β in-progress β completed) - Publish/consume Kafka events (e.g., ride started, completed)
- Expose HTTP APIs:
/requestRide/rideStatus/cancelRide
Purpose: Handle real-time geolocation tracking
Responsibilities:
- Track and update driver/rider locations
- Use Uber H3 for geospatial indexing
- Find nearby drivers or riders
- Publish/consume location updates via Kafka/RabbitMQ
- Provide real-time location services
Before committing, run the automated UserManager workflow script to ensure the core CRUD paths behave as expected and that transient files are handled safely:
scripts/test_usermanager_workflow.shThe helper waits for the service to accept TCP connections on
USER_SERVICE_HOST:USER_SERVICE_PORT (defaults to localhost:8081), then
executes a signup β login β profile update β password change β delete flow. It
fails fast when HTTP responses deviate from the expected contracts or when the
response body is missing, preventing cat: response.txt: No such file or directory style errors.
Set USER_SERVICE_HOST/USER_SERVICE_PORT to target a remote deployment if
needed.
- ποΈ Dedicated SQL Database (MySQL/PostgreSQL/SQLite)
- π HTTP Server for exposing REST APIs
- π‘ Kafka Handler for event messaging (Producer + Consumer)
- π¬ RabbitMQ Handler (optional command queue with thread-safe in-memory fallback)
- π gRPC Bootstrap Helpers (background server lifecycle management)
- π gRPC Client/Server (optional internal communication)
- π§΅ Thread Pool for async task execution
- π Singleton Logger with colored output
- π .env / Env Variable Config Loader
π Important: Kafka and RabbitMQ must be running before you start the service binaries.
You can start Kafka and RabbitMQ using Docker (recommended) or your local installation.
conan build . --output-folder=build --build=missingThen run the binaries from ./build/Release/bin/ as needed.
docker build -f docker/Dockerfile.base -t uber_base:latest .
docker compose -f docker/docker-compose.test-deploy.yml --env-file .env build
docker compose -f docker/docker-compose.test-deploy.yml --env-file .env up -dBring the stack down when finished:
docker compose -f docker/docker-compose.test-deploy.yml downThis project supports a fully containerized microservices environment using Docker Compose.
| Service | Description | Port |
|---|---|---|
mysql_user |
MySQL for UserManager | ${USERMANAGER_PORT} |
mysql_ride |
MySQL for RideManager | ${RIDEMANAGER_PORT} |
mysql_location |
MySQL for LocationManager | ${LOCATIONMANAGER_PORT} |
kafka |
Kafka broker (KRaft mode) | ${KAFKA_EXTERNAL_PORT:-9092} |
rabbitmq |
RabbitMQ broker + management UI | ${RABBITMQ_AMQP_PORT:-5672}/${RABBITMQ_HTTP_PORT:-15672} |
redis |
Redis cache | ${REDIS_PORT:-6379} |
usermanager |
UserManager C++ microservice | ${USERMANAGER_APP_PORT} |
ridemanager |
RideManager C++ microservice | ${RIDEMANAGER_APP_PORT} |
locationmanager |
LocationManager C++ microservice | ${LOCATIONMANAGER_APP_PORT} |
Set your values in a .env file at the project root:
# MySQL shared config
MYSQL_ROOT_PASSWORD=yourRootPassword
MYSQL_USER=uber
MYSQL_PASSWORD=securepass
# Databases
USERMANAGER_DB=userdb
RIDEMANAGER_DB=ridedb
LOCATIONMANAGER_DB=locationdb
# DB Ports
USERMANAGER_PORT=3307
RIDEMANAGER_PORT=3308
LOCATIONMANAGER_PORT=3309
# Application Ports
USERMANAGER_APP_PORT=8081
RIDEMANAGER_APP_PORT=8082
LOCATIONMANAGER_APP_PORT=8083
# gRPC Ports
LOCATION_MANAGER_GRPC_PORT=50051
# RabbitMQ
RABBITMQ_HOST=localhost
RABBITMQ_PORT=5672
RABBITMQ_USERNAME=guest
RABBITMQ_PASSWORD=guest
RABBITMQ_VHOST=/π‘ Tip: When running inside the provided Docker Compose stack, set service hosts (e.g.,
USER_MANAGER_HOST,RIDE_MANAGER_HOST,LOCATION_MANAGER_HOST,KAFKA_HOST,RABBITMQ_HOST,REDIS_HOST) to the matching container names (usermanager,ridemanager,locationmanager,kafka-bus,rabbitmq-bus,redis-cache).
docker compose -f docker/docker-compose.test-deploy.yml --env-file .env up -d- Review the Code of Conduct to understand the expectations for participating in this community.
- See the Contributing Guide for instructions on setting up your environment, coding standards, and submitting pull requests.
- Consult the Security Policy for guidance on how to responsibly disclose vulnerabilities.
- This project is distributed under the terms of the MIT License.
