StayEase is a backend service built with Java and Spring Boot that provides REST APIs for managing hotels and room bookings in a hotel aggregator platform.
The application supports JWT-based authentication, role-based access control (RBAC), and uses MySQL for persistent storage.
- Java
- Spring Boot
- Spring Security
- JWT Authentication
- MySQL
- JPA / Hibernate
- Gradle
- User registration and login with JWT authentication
- Role-based access control (ADMIN, HOTEL_MANAGER, USER)
- Hotel listing and management APIs
- Room booking creation and cancellation
- Layered architecture (Controller → Service → Repository)
Client (Postman / Curl / Frontend)
|
v
Controller Layer → Service Layer → Repository Layer → MySQL DB
|
v
Security Layer (JWT + Roles)
src/main/java/com/takehome/stayease
│
├── controller
│ ├── AuthController.java
│ ├── HotelController.java
│ └── BookingController.java
│
├── service
│ ├── UserService.java
│ ├── HotelService.java
│ ├── BookingService.java
│ └── Impl
│ ├── UserServiceImpl.java
│ ├── HotelServiceImpl.java
│ └── BookingServiceImpl.java
│
├── repository
│ ├── UserRepository.java
│ ├── HotelRepository.java
│ └── BookingRepository.java
│
├── entity
│ ├── User.java
│ ├── Hotel.java
│ └── Booking.java
│
├── dto
│ ├── auth
│ │ ├── SignupRequest.java
│ │ ├── LoginRequest.java
│ │ └── AuthResponse.java
│ │
│ ├── hotel
│ │ ├── CreateHotelRequest.java
│ │ ├── UpdateHotelRequest.java
│ │ └── HotelResponse.java
│ │
│ └── booking
│ ├── CreateBookingRequest.java
│ └── BookingResponse.java
│
├── security
│ ├── SecurityConfig.java
│ ├── JwtUtil.java
│ ├── JwtAuthenticationFilter.java
│ ├── CustomUserDetails.java
│ └── CustomUserDetailsService.java
│
├── exception
│ └── GlobalExceptionHandler.java
│
└── StayEaseApplication.java
| Role | Permissions |
|---|---|
| USER | View hotels, create booking |
| HOTEL_MANAGER | Update hotels, cancel bookings |
| ADMIN | Create hotels, delete hotels |
Implemented using:
@PreAuthorize("hasRole('ADMIN')")
@PreAuthorize("hasRole('HOTEL_MANAGER')")
@PreAuthorize("hasRole('USER')")JWT token contains role information and is validated on every request.
- User registers or logs in
- Server validates credentials
- JWT token is generated
- Client sends token in header:
Authorization: Bearer <JWT_TOKEN> - JWT filter validates token and sets security context
POST /api/users/register{
"email": "user@test.com",
"password": "Test@1234",
"firstName": "John",
"lastName": "Doe",
"role": "USER"
}Response:
{ "token": "jwt-token" }POST /api/users/login{
"email": "user@test.com",
"password": "Test@1234"
}Response:
{ "token": "jwt-token" }GET /api/hotelsPOST /api/hotels
Authorization: Bearer <ADMIN_TOKEN>{
"name": "StayEase Hotel",
"location": "Pune",
"description": "Business Hotel",
"totalRooms": 10,
"availableRooms": 10
}PUT /api/hotels/{hotelId}
Authorization: Bearer <MANAGER_TOKEN>{
"availableRooms": 15
}DELETE /api/hotels/{hotelId}
Authorization: Bearer <ADMIN_TOKEN>POST /api/bookings/{hotelId}
Authorization: Bearer <USER_TOKEN>{
"checkInDate": "2026-02-20",
"checkOutDate": "2026-02-22"
}Response:
{
"bookingId": 1,
"hotelId": 2,
"checkInDate": "2026-02-20",
"checkOutDate": "2026-02-22"
}GET /api/bookings/{bookingId}
Authorization: Bearer <USER_TOKEN>DELETE /api/bookings/{bookingId}
Authorization: Bearer <MANAGER_TOKEN>- Check-in date must be future date
- Check-out date must be after check-in
- No overbooking allowed
- Customers cannot cancel bookings
- Only managers can cancel bookings
- Controller-level unit tests
- MockMvc + Mockito
- Security filters disabled during tests
- No real DB used in tests
Run tests:
./gradlew test./gradlew clean bootRunApp runs on:
http://localhost:8081
./gradlew clean bootJar
java -jar build/libs/stayease-0.0.1-SNAPSHOT.jar