NxtShow is a production-grade, highly scalable Spring Boot backend designed for movie and event show bookings. It implements a clean layered architecture with a stateless JWT-based authentication system, input validation, and centralized exception handling.
The application is built using Spring Boot 4.1.0 (with Java 25) and standard production-ready frameworks:
- Core Framework: Spring Boot Starter Web (MVC)
- Data Persistence: Spring Data JPA + H2 Database (in-memory, run-ready) / PostgreSQL (production profiles)
- Security: Spring Security 6 + stateless JWT
- JSON Processing: Jackson Databind + JSR310 Datatypes
- Tooling: Lombok, Validation Starter, Maven
The codebase enforces a strict separation of concerns through the following layers:
- Model (JPA Entities): Direct mapping to relational tables. Includes optimistic locking (
@Version) for seat reservation concurrency. - Repository (Data Access): Spring Data JPA interfaces for database operations.
- DTO (Data Transfer Objects): Strict input/output contracts with validation constraints (
@NotBlank,@Min,@Size, etc.). - Service (Business Logic): Interface-based implementations of core processes (pricing adjustments, booking verification, token rotation).
- Controller (REST API): REST endpoints mapping requests, enforcing validation, and handling custom response formatting.
- Security & Configuration: Customized Spring Security filter chains and stateless token validation.
- Exception: Centralized exception handling using
@RestControllerAdvicereturning structuredErrorResponsepayloads.
The package structure under src/main/java/org/show/nxtshow is laid out as follows:
org.show.nxtshow
├── NxtShowApplication.java
├── config
│ ├── AppConfig.java # Beans for PasswordEncoder & AuthManager
│ └── SecurityConfig.java # HttpSecurity configuration & access rules
├── controller
│ ├── AuthController.java # SignUp, Login, Refresh, Logout endpoints
│ ├── MovieController.java # Movie CRUD APIs
│ ├── ShowController.java # Show scheduling & seat mapping
│ ├── TheatreController.java # Theatre & Screen configuration
│ ├── BookingController.java # Booking reservation lifecycle
│ ├── PaymentController.java # Mock Payment verification
│ └── ReviewController.java # Movie reviews & ratings
├── dto
│ ├── SignUpRequest.java / LoginRequest.java / AuthResponse.java
│ ├── MovieRequest.java / MovieResponse.java
│ ├── ShowRequest.java / ShowResponse.java / ShowSeatResponse.java
│ ├── TheatreRequest.java / TheatreResponse.java
│ ├── ScreenRequest.java / ScreenResponse.java / SeatResponse.java
│ ├── BookingRequest.java / BookingResponse.java
│ ├── PaymentRequest.java / PaymentResponse.java
│ └── ReviewRequest.java / ReviewResponse.java
├── exception
│ ├── ResourceNotFoundException.java # Custom 404 Exception
│ ├── BadRequestException.java # Custom 400 Exception
│ ├── UnauthorizedException.java # Custom 401 Exception
│ ├── ErrorResponse.java # Structured JSON error layout
│ └── GlobalExceptionHandler.java # Centralized Exception Handler
├── model
│ ├── User.java # User details
│ ├── RefreshToken.java # Active refresh token storage
│ ├── Movie.java # Movie details
│ ├── Theatre.java / Screen.java # Venues & screens
│ ├── Seat.java # Physical seat maps
│ ├── Show.java # Show details (movie + screen + timing)
│ ├── ShowSeat.java # Interactive seat availability
│ ├── Booking.java # Seat reservation details
│ ├── Payment.java # Payment transactions
│ └── Review.java # Movie ratings & comments
├── repository
│ └── UserRepository.java / RefreshTokenRepository.java / MovieRepository.java / etc.
└── security
├── JwtUtils.java # Access/Refresh token generation & validation
├── UserDetailsImpl.java # Custom Principal representation
├── CustomUserDetailsService.java # Database user loading
└── JwtAuthenticationFilter.java # Custom JWT header validation filter
The backend implements stateless token-based authentication using Spring Security 6.
- User Sign Up / Login: Authenticates credentials and returns a short-lived Access Token (JWT, 15-minute expiry) and a long-lived Refresh Token (UUID, 7-day expiry, persisted in database).
- Stateless JWT Verification: For protected resources, the client must include the Access Token in the
Authorization: Bearer <token>header. - Custom
JwtAuthenticationFilter: ExtendsOncePerRequestFilter. It extracts the token, validates the signature/expiration usingJwtUtils, parses the subject (username), and manually populates Spring'sSecurityContextHolder. - Token Rotation (Refresh): When the Access Token expires, clients call the
/refreshendpoint with the Refresh Token. The system validates the token against the database, verifies its expiration, deletes the old token, and generates a new Access/Refresh token pair (Rotation). - Logout: Deletes the user's refresh token from the database, invalidating the session.
- Authentication Entry Point: Unauthenticated attempts to access secure routes bypass standard HTML redirects and are intercepted by
CustomAuthenticationEntryPoint, which returns a clean, structured JSON 401 response.
All endpoints are under /api/v1/auth and do not require authentication.
| Method | Endpoint | Description | Request Payload | Response Code |
|---|---|---|---|---|
| POST | /api/v1/auth/signup |
Registers a new user and logs them in. | SignUpRequest |
200 OK (AuthResponse) |
| POST | /api/v1/auth/login |
Authenticates user credentials. | LoginRequest |
200 OK (AuthResponse) |
| POST | /api/v1/auth/refresh |
Rotates and re-issues tokens. | TokenRefreshRequest |
200 OK (TokenRefreshResponse) |
| POST | /api/v1/auth/logout |
Invalidates user refresh tokens (requires auth header). | None | 200 OK (Plain Text) |
- Movie creation/updating/deletion requires authentication.
- Movie and review listing endpoints are public.
| Method | Endpoint | Description | Request Payload | Access |
|---|---|---|---|---|
| POST | /api/v1/movies |
Create a movie. | MovieRequest |
Authenticated |
| GET | /api/v1/movies |
List all movies. | None | Public |
| GET | /api/v1/movies/{id} |
Get movie details. | None | Public |
| PUT | /api/v1/movies/{id} |
Update movie details. | MovieRequest |
Authenticated |
| DELETE | /api/v1/movies/{id} |
Delete movie. | None | Authenticated |
| POST | /api/v1/movies/{movieId}/reviews |
Write a movie review. | ReviewRequest |
Authenticated |
| GET | /api/v1/movies/{movieId}/reviews |
List movie reviews. | None | Public |
| DELETE | /api/v1/movies/reviews/{id} |
Delete a review. | None | Authenticated (Author only) |
- Theatre/Screen configuration requires authentication.
- Read-only queries are public.
| Method | Endpoint | Description | Request Payload | Access |
|---|---|---|---|---|
| POST | /api/v1/theatres |
Create a theatre. | TheatreRequest |
Authenticated |
| GET | /api/v1/theatres |
List all theatres. | None | Public |
| GET | /api/v1/theatres/{id} |
Get theatre details. | None | Public |
| POST | /api/v1/theatres/{theatreId}/screens |
Create a screen with seats. | ScreenRequest |
Authenticated |
| GET | /api/v1/theatres/{theatreId}/screens |
Get screen listings. | None | Public |
| GET | /api/v1/theatres/screens/{screenId}/seats |
Fetch layout/seats of a screen. | None | Public |
- Booking/payments require authentication.
- Scheduling shows requires authentication.
- Show lists/seats are public.
| Method | Endpoint | Description | Request Payload | Access |
|---|---|---|---|---|
| POST | /api/v1/shows |
Schedule a show & generate seat map. | ShowRequest |
Authenticated |
| GET | /api/v1/shows |
List all shows. | None | Public |
| GET | /api/v1/shows/{id} |
Get show details. | None | Public |
| GET | /api/v1/shows/movie/{movieId} |
List shows showing a movie. | None | Public |
| GET | /api/v1/shows/{showId}/seats |
View availability/status of show seats. | None | Public |
| POST | /api/v1/bookings |
Lock seats & initiate pending booking. | BookingRequest |
Authenticated |
| GET | /api/v1/bookings/{id} |
Fetch specific booking status. | None | Authenticated (Owner only) |
| GET | /api/v1/bookings/my |
List authenticated user's bookings. | None | Authenticated |
| POST | /api/v1/bookings/{id}/cancel |
Cancel booking and release seats. | None | Authenticated (Owner only) |
| POST | /api/v1/payments |
Process mock payment to confirm booking. | PaymentRequest |
Authenticated |
This project uses PostgreSQL as the database.
- Java 21+ (or your project's required version)
- Maven
- PostgreSQL
git clone <repository-url>
cd NxtShowCreate a database named:
nxtshow
Update your application.properties (or .env if you're using one) with your PostgreSQL credentials:
spring.datasource.url=jdbc:postgresql://localhost:5432/nxtshow
spring.datasource.username=your_username
spring.datasource.password=your_password./mvnw clean install./mvnw spring-boot:runThe application will start at:
http://localhost:8081
./mvnw test