A production-grade ride-hailing REST API inspired by Uber, built with Spring Boot and deployed on AWS.
Features JWT-based authentication, role-based access control, geolocation-aware ride matching using PostGIS, wallet-based payment system, email notifications via Gmail SMTP, and a fully automated CI/CD pipeline from GitHub to AWS Elastic Beanstalk.
| Component | Service |
|---|---|
| App Hosting | AWS Elastic Beanstalk (EC2 + Load Balancer + Auto Scaling) |
| Database | AWS RDS (PostgreSQL) |
| CI/CD | AWS CodePipeline + CodeBuild |
| Source | GitHub (main branch) |
- JWT access + refresh token flow
- Role-based access control:
RIDER,DRIVER,ADMIN - Signup auto-creates Rider profile + Wallet
- Rider requests ride with pickup + drop coordinates
- Nearest available Driver matched using PostGIS geospatial queries
- Ride status transitions:
REQUESTED → CONFIRMED → ONGOING → ENDED - Driver can accept or cancel; Rider can cancel before confirmation
- Every user gets a Wallet on signup
- Fare auto-deducted from Rider wallet on ride end
- Driver wallet credited; full transaction history maintained
- Strategy pattern used for payment processing
- Rider rates Driver after ride ends
- Driver rates Rider after ride ends
- Average ratings tracked on profiles
- Gmail SMTP integration for ride confirmations and updates
| Method | Endpoint | Description | Access |
|---|---|---|---|
| POST | /auth/signup |
Register new user | Public |
| POST | /auth/login |
Login, get JWT tokens | Public |
| POST | /auth/refresh |
Refresh access token | Public |
| POST | /auth/onBoardNewDriver/{userId} |
Onboard new driver | ADMIN |
| Method | Endpoint | Description | Access |
|---|---|---|---|
| POST | /rider/requestRide |
Request a new ride | RIDER |
| POST | /rider/cancelRide/{rideId} |
Cancel a ride | RIDER |
| POST | /rider/rateDriver/{rideId} |
Rate driver after ride | RIDER |
| GET | /rider/getMyRides |
Get all past rides | RIDER |
| GET | /rider/getMyProfile |
Get rider profile | RIDER |
| Method | Endpoint | Description | Access |
|---|---|---|---|
| POST | /driver/acceptRide/{rideRequestId} |
Accept a ride request | DRIVER |
| POST | /driver/startRide/{rideRequestId} |
Start the ride | DRIVER |
| POST | /driver/endRide/{rideId} |
End the ride | DRIVER |
| POST | /driver/cancelRide/{rideId} |
Cancel a ride | DRIVER |
| POST | /driver/rateRider/{rideId} |
Rate rider after ride | DRIVER |
| GET | /driver/getMyRides |
Get all past rides | DRIVER |
| GET | /driver/getMyProfile |
Get driver profile | DRIVER |
PostgreSQL with PostGIS extension for geospatial support.
Key entities:
User ──< Rider
──< Driver
── Wallet ──< WalletTransaction
RideRequest ──> Ride ──> Payment
──> Rating
app_user— core user with rolesrider/driver— profile tables linked to userride_request— pending requests with pickup/drop Point coordinatesride— active and completed rideswallet/wallet_transaction— full payment ledgerrating— post-ride ratings for both parties
Initial seed data loaded via data.sql on startup (dev profile).
- JUnit 5 + Mockito — Unit tests with fully mocked dependencies, no DB required
- Testcontainers — Integration tests spin up a real PostgreSQL Docker container
- Tests cover: Auth Controllers, Auth Service, Repository layer
- Docker Hub credentials configured in CodeBuild to pull PostgreSQL image for Testcontainers
# Run all tests
mvn testTestContainerConfiguration.java uses @ServiceConnection — Spring Boot auto-configures datasource from the container, no manual URL setup needed.
- AWS Console → RDS → Create database
- Engine: PostgreSQL
- Template: Free tier
- DB instance identifier:
transitx-db - Master username & password set
- Connectivity: VPC default (accessible from EB environment)
- Create database
- AWS Console → Elastic Beanstalk → Create application
- Application name:
springboot-transitx - Platform: Corretto 21 (Java)
- Environment type: Load balanced
- Configure environment variables:
SPRING_PROFILES_ACTIVE=prodDB_URL= RDS endpointDB_USERNAME= RDS usernameDB_PASSWORD= RDS password
- Create environment
- AWS Console → CodeBuild → Create build project
- Source: GitHub → repository connect
- Buildspec: Use buildspec.yml from repo
- Artifacts: Amazon S3
- Configure environment variables:
DOCKER_USERNAME= Docker Hub usernameDOCKER_PASSWORD= Docker Hub password
- Create build project
- AWS Console → CodePipeline → Create pipeline
- Source stage: GitHub → main branch
- Build stage: CodeBuild project select
- Deploy stage: Elastic Beanstalk → environment select
- Create pipeline
- IAM → Roles →
AWSCodePipelineServiceRole-ap-south-1-transitx-pipeline - Add permissions → Attach policies
- Attach:
AdministratorAccess-AWSElasticBeanstalk
- CodePipeline → Settings → Connections
- Create connection → GitHub
- Authorize AWS to access GitHub repo
Push to main → CodePipeline triggers → Docker Hub login → Maven build & test → JAR artifact → Elastic Beanstalk deploys
version: 0.2
phases:
install:
runtime-versions:
java: corretto21
commands:
- echo Installing Maven...
pre_build:
commands:
- echo Logging in to Docker Hub...
- echo $DOCKER_PASSWORD | docker login -u $DOCKER_USERNAME --password-stdin
build:
commands:
- echo Building, Testing, and Packaging the application...
- mvn package
post_build:
commands:
- echo Build, Testing, and Packaging completed.
artifacts:
files:
- target/*.jar
discard-paths: yes
cache:
paths:
- '/root/.m2/**/*'| Profile | Usage |
|---|---|
dev |
Local development with RDS config (credentials in application-dev.properties) |
local |
Local development with local PostgreSQL |
prod |
AWS production — RDS PostgreSQL, port 5000 |
# Run with dev profile (uses RDS, real DB)
mvn spring-boot:run -Dspring-boot.run.profiles=dev
# Run with local profile
mvn spring-boot:run -Dspring-boot.run.profiles=local
# Run with prod profile
mvn spring-boot:run -Dspring-boot.run.profiles=prod
⚠️ application-dev.propertiescontains real credentials and is git-ignored. Useapplication-dev-example.propertiesas a reference to create your own.
transitx/
├── src/
│ ├── main/
│ │ ├── java/com/springboot/transitx/
│ │ │ ├── controllers/ # REST Controllers (Auth, Rider, Driver)
│ │ │ ├── services/ # Service interfaces
│ │ │ │ └── impl/ # Service implementations
│ │ │ ├── entities/ # JPA Entities
│ │ │ │ └── enums/ # Role, RideStatus, PaymentStatus...
│ │ │ ├── repositories/ # Spring Data JPA Repositories
│ │ │ ├── dto/ # Request/Response DTOs
│ │ │ ├── security/ # JWT filter, JWTService, SecurityConfig
│ │ │ ├── strategies/ # Strategy pattern (Payment, RideFare, DriverMatching)
│ │ │ ├── utilis/ # GeometryUtil (PostGIS helpers)
│ │ │ └── exceptions/ # Global exception handling
│ │ └── resources/
│ │ ├── application.properties # Base config
│ │ ├── application-dev.properties # Dev profile — git-ignored
│ │ ├── application-dev-example.properties # Dev config template
│ │ ├── application-local.properties # Local DB config
│ │ ├── application-prod.properties # Prod profile config
│ │ └── data.sql # Seed data (dev profile)
│ └── test/
│ └── java/com/springboot/transitx/
│ ├── TestContainerConfiguration.java # Testcontainers setup
│ ├── TransitXApplicationTests.java # Context load test
│ ├── controllers/ # Controller integration tests
│ └── services/impl/ # Service unit tests
├── buildspec.yml # CodeBuild configuration
├── pom.xml # Maven dependencies
└── README.md
Prerequisites: Java 21+, Maven, PostgreSQL, Docker
git clone https://github.com/MansiArora-dev/transitx.git
cd transitx
# Copy example config and fill in your values
cp src/main/resources/application-dev-example.properties \
src/main/resources/application-dev.propertiesConfigure application-dev.properties with your DB, SMTP, and JWT credentials
using application-dev-example.properties as reference.
# Run with dev profile
mvn spring-boot:run -Dspring-boot.run.profiles=dev- Java 21 | Spring Boot 3.5 | Maven
- AWS — Elastic Beanstalk, RDS, CodePipeline, CodeBuild
- PostgreSQL | PostGIS | Spring Security | JWT
- Gmail SMTP | Docker | Testcontainers | JUnit 5 | Mockito
- ModelMapper | Lombok | Strategy Design Pattern
Mansi Arora — Software Engineer GitHub