A complete serverless ride-sharing application built with Java, AWS Lambda, API Gateway, RDS, and Bootstrap frontend hosted on S3.
Live Frontend: http://cab-booking-app-frontend.s3-website.ap-south-1.amazonaws.com/
graph TB
User["👤 User Browser"]
S3["📦 S3 Static Hosting<br/>(Frontend)"]
APIGW["🚪 API Gateway<br/>(REST API)"]
Lambda["⚡ Lambda<br/>(Java 17)"]
RDS["🗄️ RDS MySQL<br/>(cab_booking_db)"]
User -->|HTTPS| S3
User -->|API Calls| APIGW
APIGW -->|Proxy Integration| Lambda
Lambda -->|TCP 3306| RDS
S3 -->|Embedded API URL| S3
style User fill:#e1f5ff
style S3 fill:#fff3e0
style APIGW fill:#f3e5f5
style Lambda fill:#e8f5e9
style RDS fill:#fce4ec
| Component | Purpose | Technology |
|---|---|---|
| Frontend | User interface for booking/publishing rides | Bootstrap 5, Vanilla JS, HTML |
| API Gateway | REST endpoint for all backend operations | AWS REST API with proxy integration |
| Lambda | Business logic & database interaction | Java 17, Stateless handler |
| RDS MySQL | Persistent storage for users, rides, bookings | AWS RDS in VPC |
- Chose Lambda over EC2 to avoid server management and reduce costs
- Each request is stateless, allowing auto-scaling
- No need to manage deployment infrastructure
- Three main tables:
users,rides,bookings - Foreign keys ensure referential integrity
- Auto-generated IDs for simplified tracking
- Timestamps for audit trails
- Booking operations use database transactions to prevent race conditions
- When a user books a ride, seats are atomically reduced
- If booking fails, seats are rolled back—no inconsistency
- Standard HTTP verbs: GET (fetch), POST (create), DELETE (remove)
- Query params for optional filtering (e.g., search by source/destination)
- Standard JSON responses with CORS enabled
- API URL locked in
config.jsat build time (S3 hosting) - No manual URL input field required for users
- Local storage only used for future session persistence (optional)
.envfile for local development (ignored by git)- Lambda env vars for AWS deployment
- Fallback defaults to prevent hard failures
Problem: Initial Lambda zip had function.jar nested inside, causing Class not found error.
- Lambda couldn't find
api.LambdaHandlerbecause it was looking at the zip root, not inside a nested jar
Solution: Modified packaging script to extract fat jar contents into zip root
- Now
lambda_pkg.zipcontains classes and dependencies directly at root level - Lambda classpath can now discover all compiled classes
Problem: Lambda kept hitting "Database error: Failed to initialize schema" even with correct env vars
Solution: Multi-step debugging:
- Moved
/healthendpoint before DB initialization (to separate network issues from code issues) - Verified Lambda security group had inbound MySQL access to RDS
- Ensured Lambda was in same VPC as RDS
- Fixed typo in
DB_PASSenv var (hadDB_PASS=prefix in value) - Confirmed RDS
cab_bookingdatabase existed
Problem: API Gateway wasn't sending HTTP method/path to Lambda handler
Solution: Enabled Lambda Proxy Integration
- REST API requires explicit proxy integration toggle
- Once enabled, Lambda receives full
APIGatewayProxyRequestEventwith method, path, headers, body - Without it, Lambda receives old format without path information
Problem: Frontend input field for API URL could be incorrectly changed by users
Solution: Removed UI input field and locked API URL to config.js
- URL set at build time, not runtime
- Users cannot accidentally point frontend to wrong API
- Still supports localhost for development
Problem: Maven build artifacts and compiled classes added 3,000+ files to git
Solution: Enhanced .gitignore
- Added
/target/ - Excluded
*.jar,*.class, build artifacts - Removed cached files from tracking with
git rm --cached
- Runtime: Java 17
- Handler:
api.LambdaHandler - Build: Maven shaded JAR (
target/cab-booking-lambda.jar) - Database: MySQL-compatible RDS (env-based configuration)
GET /health— Health checkPOST /users/registerbody:{ "name": "...", "email": "..." }GET /users/login?email=...POST /ridesbody:{ "ownerId": 1, "source": "A", "destination": "B", "seats": 3, "farePerSeat": 200 }GET /rides— List all available ridesGET /rides?source=A&destination=B— Search rides by routeDELETE /rides/{rideId}?ownerId=1— Cancel a ridePOST /bookingsbody:{ "rideId": 1, "userId": 2, "seats": 1 }GET /bookings/{userId}— View user's bookingsDELETE /bookings/{bookingId}?userId=2— Cancel a booking
Set these in Lambda configuration:
DB_HOST— RDS endpointDB_PORT— Default:3306DB_NAME— Default:cab_bookingDB_USER— Database usernameDB_PASS— Database password
For local development, use .env file in project root:
DB_HOST=cab-booking-db.c904uaymsnn9.ap-south-1.rds.amazonaws.com
DB_PORT=3306
DB_NAME=cab_booking
DB_USER=admin
DB_PASS=<your-password>Lookup order:
- OS environment variables (Lambda)
.envfile values (local dev)- Code defaults
mvn clean package./scripts/build_lambda_zip.shOutputs:
lambda_pkg/— Extracted classes and dependencieslambda_pkg.zip— Ready for Lambda upload
Lambda Console settings:
- Runtime:
Java 17 - Handler:
api.LambdaHandler::handleRequest
- Create Lambda function (Java 17)
- Upload
lambda_pkg.zipvia Lambda Console - Set handler to:
api.LambdaHandler::handleRequest - Add environment variables (
DB_HOST,DB_PORT,DB_NAME,DB_USER,DB_PASS) - Create REST API in API Gateway
- Add resource
/{proxy+}withANYmethod - Enable Lambda Proxy Integration on the method
- Deploy to stage (e.g.,
prod) - Note the invoke URL (e.g.,
https://8wl89zpued.execute-api.ap-south-1.amazonaws.com/prod)
Frontend lives in frontend/ with Bootstrap assets in frontend/assets/.
Deployment:
- Update
frontend/config.js:
window.CAB_CONFIG = {
apiBaseUrl: "https://<your-api-id>.execute-api.<region>.amazonaws.com/<stage>"
};- Create S3 bucket
- Upload entire
frontend/folder - Enable Static website hosting in bucket properties
- Set index document to
index.html - Configure bucket policy for public access if needed
Live Site: http://cab-booking-app-frontend.s3-website.ap-south-1.amazonaws.com/
mvn clean package
java -cp target/cab-booking-lambda.jar Maincd frontend
python3 -m http.server 5500
# Open http://localhost:5500.
├── src/
│ ├── api/
│ │ └── LambdaHandler.java # AWS Lambda entry point
│ ├── db/
│ │ └── DBConnection.java # RDS connectivity + schema init
│ ├── dao/
│ │ ├── UserDAO.java
│ │ ├── RideDAO.java
│ │ └── BookingDAO.java
│ ├── model/
│ │ ├── User.java
│ │ ├── Ride.java
│ │ └── Booking.java
│ ├── service/
│ │ ├── UserService.java
│ │ ├── RideService.java
│ │ └── BookingService.java
│ └── Main.java
├── frontend/
│ ├── index.html # Primary UI
│ ├── app.js # Business logic
│ ├── styles.css # Custom styles
│ ├── config.js # API configuration
│ └── assets/
│ ├── css/ # Bootstrap CSS
│ └── js/ # Bootstrap JS
├── scripts/
│ └── build_lambda_zip.sh # Zero-config deployment script
├── pom.xml # Maven build config
├── .env # Local DB credentials (git-ignored)
├── .env.example # Template for .env
└── README.md # This file
✅ Fully Serverless: No servers to manage, auto-scaling out of the box
✅ Transaction-Safe: Race condition prevention via database transactions
✅ Environment-Agnostic: Works locally with .env, on Lambda with env vars
✅ Frontend Decoupled: S3 hosting completely independent of backend
✅ Single Packaging: One script builds and prepares deployment
✅ Bootstrap UI: Responsive, modern interface without complex dependencies
Built with: Java 17 | AWS Lambda | API Gateway | RDS MySQL | Bootstrap 5 | S3