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