A full-stack ride booking web application built for the NextGen Innovations internship assessment. Riders can view available drivers, book a ride with pickup and drop-off locations, and receive instant driver assignment with a confirmation screen.
- Driver availability — Live list of drivers ready to accept rides
- One-click booking — Submit pickup and drop-off locations from a responsive React UI
- Automatic assignment — First available driver is assigned atomically on booking
- Booking confirmation — Shows assigned driver name, phone, and vehicle type
- Graceful errors — Clear feedback when no drivers are available or validation fails
- REST API + Swagger — Full backend API with interactive documentation for testing and seeding data
| Layer | Technologies |
|---|---|
| Backend | Spring Boot 4, Java 21, Spring Data JPA, Spring Validation |
| Database | PostgreSQL |
| Frontend | React 19, Vite 6 |
| API Docs | springdoc-openapi (Swagger UI) |
Ride Booking Application/
├── demo/ # Spring Boot backend
│ ├── src/main/java/com/ridebooking/demo/
│ │ ├── config/ # CORS configuration
│ │ ├── controllers/ # REST controllers
│ │ ├── dto/ # Request/response DTOs
│ │ ├── entity/ # JPA entities (drivers, bookings)
│ │ ├── exceptions/ # Custom exceptions + global handler
│ │ ├── repository/ # Spring Data repositories
│ │ └── service/ # Business logic
│ └── src/main/resources/
│ └── application.properties
└── frontend/ # React (Vite) client
└── src/
├── api.js # HTTP client for backend API
├── App.jsx # App shell and navigation
└── components/ # HomeScreen, BookingForm, DriverList, Confirmation
┌─────────────┐ HTTP (REST) ┌──────────────────┐ JPA ┌────────────┐
│ React UI │ ──────────────────► │ Spring Boot API │ ───────────► │ PostgreSQL │
│ (Vite) │ ◄────────────────── │ (port 8080) │ ◄─────────── │ │
└─────────────┘ └──────────────────┘ └────────────┘
:5173 │
└── Swagger UI (/swagger-ui)
Booking flow: The frontend calls POST /api/bookings. The service finds the first available driver, creates a booking record, marks the driver as busy, and returns a structured response — all within a single @Transactional method.
- Java 21+
- Maven (or use the included wrapper in
demo/) - Node.js 18+ and npm
- PostgreSQL running locally (or accessible remotely)
Create a PostgreSQL database:
CREATE DATABASE ride_booking_db;Edit demo/src/main/resources/application.properties with your PostgreSQL credentials:
spring.datasource.url=jdbc:postgresql://localhost:5432/ride_booking_db
spring.datasource.username=your_username
spring.datasource.password=your_passwordNote: Do not commit real database passwords. Use local configuration only.
Hibernate auto-creates and updates tables (drivers, bookings) on startup via spring.jpa.hibernate.ddl-auto=update.
Windows:
cd demo
mvnw.cmd spring-boot:runmacOS / Linux:
cd demo
./mvnw spring-boot:runBackend: http://localhost:8080
cd frontend
npm install
npm run devFrontend: http://localhost:5173
By default the frontend targets http://localhost:8080. To override, create frontend/.env:
VITE_API_BASE_URL=http://localhost:8080| Resource | URL |
|---|---|
| Swagger UI | http://localhost:8080/swagger-ui/index.html |
| OpenAPI JSON | http://localhost:8080/v3/api-docs |
Use Swagger to seed drivers before using the React UI.
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/drivers/available |
List drivers with available = true |
POST |
/api/bookings |
Create a booking and assign a driver |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/drivers |
List all drivers |
POST |
/api/drivers |
Create a driver |
GET |
/api/drivers/{id} |
Get driver by ID |
PATCH |
/api/drivers/{id}/availability |
Toggle driver availability |
PUT |
/api/drivers/{id} |
Update driver |
DELETE |
/api/drivers/{id} |
Delete driver |
GET |
/api/bookings |
List all bookings |
GET |
/api/bookings/{id} |
Get booking by ID |
Create a driver (POST /api/drivers):
{
"name": "Kamal Perera",
"phone": "0771234567",
"vehicle_type": "Sedan",
"available": true
}Create a booking (POST /api/bookings):
{
"pickupLocation": "Colombo Fort",
"dropLocation": "Mount Lavinia"
}Success response (201 Created):
{
"id": 1,
"pickupLocation": "Colombo Fort",
"dropLocation": "Mount Lavinia",
"status": "ASSIGNED",
"createdAt": "2026-06-11T10:30:00",
"driver": {
"id": 1,
"name": "Kamal Perera",
"phone": "0771234567",
"vehicleType": "Sedan"
}
}| Status | Condition | Example body |
|---|---|---|
400 |
Missing pickup or drop location | { "message": "Validation failed" } |
404 |
Driver or booking not found | { "message": "Booking not found with id: 99" } |
409 |
No drivers available | { "message": "No drivers available" } |
- Start PostgreSQL, the backend, and the frontend.
- Open Swagger UI and create 2–3 drivers via
POST /api/drivers. - Open http://localhost:5173 — available drivers appear on the home screen.
- Click Book a Ride, enter pickup and drop-off locations, and submit.
- The confirmation screen shows the assigned driver details.
- Book again until all drivers are busy to verify the "No drivers available" error state.
- Use
PATCH /api/drivers/{id}/availabilityin Swagger to free a driver and book again.
- First-available assignment — Simple, deterministic driver selection suitable for an assessment demo.
- Transactional booking — Booking creation and driver status update happen in one transaction to prevent partial state.
- DTOs for bookings — Booking API uses typed request/response objects with validation; driver list returns entity JSON (
snake_casefields). - CORS — Configured for
http://localhost:5173andhttp://127.0.0.1:5173.
cd demo
mvnw.cmd test # Windows
./mvnw test # macOS / Linuxcd frontend
npm run build
npm run preview # Preview production build locally| Issue | Solution |
|---|---|
| Backend won't start | Verify PostgreSQL is running and credentials in application.properties are correct |
| Frontend can't reach API | Ensure backend is on port 8080; check VITE_API_BASE_URL if customized |
| CORS errors | Frontend must run on port 5173 (configured in CorsConfig.java) |
| No drivers in UI | Seed drivers via Swagger POST /api/drivers with "available": true |
| All bookings fail | All drivers may be busy — reset availability via PATCH /api/drivers/{id}/availability |
This project was developed as part of the NextGen Innovations internship assessment.