A production-ready Spring Boot REST API for real-time multiplayer chess, featuring JWT authentication, WebSocket-based game synchronization, and comprehensive chess logic with FEN notation.
- JWT Authentication: Secure token-based auth with HTTP-only cookies and BCrypt password hashing
- Real-time Multiplayer: WebSocket-based bidirectional communication with STOMP protocol for live game synchronization
- Complete Chess Engine: Full move validation, checkmate detection, FEN notation, and special moves (castling, en passant, promotion)
- RESTful API: 9 endpoints for auth, room management, and gameplay
- Database Persistence: PostgreSQL with JPA/Hibernate for users, rooms, and game moves
- Layered Architecture: Clean separation of concerns (Controllers β Services β Repositories)
| Technology | Version | Purpose |
|---|---|---|
| Spring Boot | 3.4.8 | Application framework |
| Java | 24 | Programming language |
| Spring Security | 6.x | Authentication & authorization |
| Spring Data JPA | 3.5.7 | ORM and data access |
| Spring WebSocket | 6.2.12 | Real-time communication with STOMP |
| PostgreSQL | Latest | Relational database |
| JJWT | 0.11.5 | JWT token management |
| Lombok | Latest | Boilerplate reduction with @Builder |
| HikariCP | Embedded | Connection pooling |
| Maven | 3.x+ | Build management |
βββββββββββββββββββββββββββββββββββββββββββ
β REST Controllers β β HTTP/WebSocket endpoints
βββββββββββββββββββββββββββββββββββββββββββ€
β Service Layer β β Business logic
βββββββββββββββββββββββββββββββββββββββββββ€
β Repository Layer β β Data access (JPA)
βββββββββββββββββββββββββββββββββββββββββββ€
β Database (PostgreSQL) β β Persistence
βββββββββββββββββββββββββββββββββββββββββββ
-
Strategy Pattern: Chess move handling in
MoveUtils.handleMove()with different strategies (handlePieceCapture(),handleCastling(),handlePawnPromotion()) for each move type -
Helper/Template Method Pattern:
RoomServiceHelperclass provides protected static methods for shared game logic, extended byRoomServicefor code reuse -
Builder Pattern with Fluent API: Lombok
@Builder+@Accessors(chain = true)for entity/DTO construction with readable chained setters -
State Machine Pattern: Explicit game state management using
GameStatusenum (WAITING,IN_PROGRESS,WHITE_WON,BLACK_WON,PAUSED) andRoomStatusenum (AVAILABLE,OCCUPIED) -
Immutable Utility Pattern: Pure functional static methods in
FenUtils,MoveUtils,CapturedPieceUtilwith no side effects for testability -
Enhanced Enum Pattern:
ChessPieceenum with domain methodsfromFenChar()andtoFenChar()for FEN notation conversion -
Custom Exception Hierarchy: Domain-specific exceptions (
RoomNotFoundException,RoomJoinNotAllowedException,MoveNotAllowed) with semantic error messages -
Error Message Enumeration:
ErrorMessageenum centralizing all error messages (ALREADY_IN_ROOM,WHITES_TURN, etc.) preventing string duplication -
Observer Pattern:
WebSocketEventsclass with@EventListenerfor handling WebSocket lifecycle (connect/disconnect) and automatic game state updates -
Centralized Constants:
RoomConstantsclass for magic values (DEFAULT_CHESSBOARD_FEN,ROOM_CODE_LENGTH, etc.) -
Broadcast Pattern:
SimpMessagingTemplateencapsulated in service methods for room-specific message distribution
1. Authentication Flow
Client β POST /auth/login β AuthService validates credentials
β
JWTService generates token β Set HTTP-only cookie β Response
β
Subsequent requests β JwtAuthenticationFilter extracts cookie β Validates β Sets SecurityContext
2. Real-time Game Synchronization
Player A submits move (POST /room/move/{code})
β
RoomService validates move β Updates FEN β Saves to DB
β
Broadcasts to WebSocket subscribers via SimpMessagingTemplate
β
Player B receives move update β UI updates board
3. WebSocket Architecture
WebSocketConfig (Spring WebSocket with STOMP)
βββ Endpoint: /room/ws/{roomCode}
βββ Authentication: JWT cookie validation
βββ Handler: RoomWebSocketHandler
β βββ onOpen: Add to subscribers
β βββ onClose: Remove from subscribers
β βββ onError: Cleanup and logging
βββ Broadcasting: ExecutorService for async
4. Chess Moves Validation Design
Move Validation Pipeline:
βββ FenUtils.parseFen() β Convert FEN to 8x8 board
βββ MoveUtils.validateMove() β Check piece-specific rules
β βββ Path clearance (sliding pieces)
β βββ Attack square detection
β βββ Special moves (castling, en passant)
βββ CapturedPieceUtil.trackCapture()
βββ Check for checkmate β isSquareAttacked()
βββ FenUtils.generateFen() β Update board state
5. Security Architecture
SecurityConfig
βββ CSRF: Disabled (REST API)
βββ Session: Stateless
βββ CORS: Configured origins with credentials
βββ Public endpoints: /auth/**, /hello-world
βββ Protected endpoints: All others
βββ Filter chain:
βββ JwtAuthenticationFilter (custom)
βββ Spring Security filters
6. Database Schema Design
Users:
id (UUID), email (unique), username (unique), password (BCrypt),
auth_provider, two_factor_enabled, is_active, in_gameRooms:
id (UUID), code (unique 6-char), fen (board state),
captured_pieces (custom format), room_status, game_status,
white_player (FK), black_player (FK), last_activityGameMoves:
id (UUID), room_id (FK), moved_by (FK),
move_number, move_notation (algebraic)Java 24+, Maven 3+, PostgreSQLexport JWT_KEY="your-base64-secret-key"
export JWT_EXPIRATION="PT24H"
export DB_URL="jdbc:postgresql://host:5432/mychess"
export DB_USERNAME="your-db-username"
export DB_PASSWORD="your-db-password"# Clone repository
git clone https://github.com/Dev-Code24/My-Chess-Backend
cd My-Chess-Backend
# Install dependencies
mvn clean install
# Run application
mvn spring-boot:run
# Access API
# Base URL: http://localhost:8080POST /auth/signup # User registration
POST /auth/login # User login (sets JWT cookie)GET /user/me # Get current authenticated userPOST /room/create # Create new game room
POST /room/join # Join existing room (body: { "code": "ABC123" })
GET /room/{code} # Get room details
POST /room/move/{code} # Submit chess movews://localhost:8080/room/ws/{roomCode}
Message Types:
- MOVE: { type: 'MOVE', move: {...}, fen: '...' }
- GAME_END: { type: 'GAME_END', winner: 'white'|'black', roomDetails: {...} }
curl -X POST http://localhost:8080/room/create \
-b cookies.txt
Response:
{
"status": "success",
"statusCode": 200,
"data": { "code": "ABC123" },
"selfLink": "/room/create"
}JWT Configuration:
- Algorithm: HS256
- Storage: HTTP-only cookies (prevents XSS)
- Expiration: 24 hours (configurable)
- Claims: email (subject), username (custom)
Password Security:
- Hashing: BCrypt with automatic salt
- Strength: 10 rounds
CORS:
- Allowed origins:
http://localhost:4200 - Credentials: true (allows cookies)
- Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS
Stateless Sessions:
- No server-side session storage
- Horizontal scaling ready
Move Validation (MoveUtils.java):
- Strategy pattern with separate handlers for each move type
- Pawn: Single/double step, diagonal capture, en passant, promotion
- Rook: Horizontal/vertical with path checking
- Knight: L-shaped movement (jumps over pieces)
- Bishop: Diagonal with path checking
- Queen: Combined rook + bishop
- King: Single square + castling validation with path and safety checks
Checkmate Detection (RoomServiceHelper.isCheckMate()):
1. Check if king is captured (targetPiece is king)
2. Update GameStatus (WHITE_WON/BLACK_WON)
3. Return boolean for game endingFEN Notation (FenUtils.java):
Format: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
βββββββββββββββββββ¬βββββββββββββββββββ β β β β β
Piece placement (8 ranks) β β β β ββ Fullmove
β β β ββ Halfmove
β β ββ En passant
β ββ Castling rights
ββ Active color
Methods:
- parseFenToPieces(): FEN string β List<Piece>
- piecesToFen(): List<Piece> β FEN string
- getTurn(): Extract current turn from FEN
Captured Pieces (CapturedPieceUtil.java):
- Custom format:
b1n1p2/R2Q1(black pieces / white pieces) - Format:
{piece_letter}{count}(e.g.,p2= 2 pawns) - Methods:
recordCapture(),parseSection(),buildSection()
- HikariCP: Maximum pool size of 5 connections with connection test query
- Async Broadcasting: ExecutorService for WebSocket messages to prevent blocking
- JPA Optimization:
spring.jpa.hibernate.ddl-auto=update(dev),validate(prod) - Builder Pattern: Lombok builders reduce object creation overhead
JWT Invalid: Check JWT_KEY environment variable is set and token hasn't expired
DB Connection Failed: Verify DB_URL, DB_USERNAME, DB_PASSWORD, ensure PostgreSQL is running
WebSocket Fails: Confirm JWT cookie is being sent, backend is running, room code is valid
CORS Errors: Update SecurityConfig allowed origins for your frontend URL
Move Validation Fails: Check MoveUtils logs, verify FEN string format
application.properties:
server.port=8080
spring.jpa.hibernate.ddl-auto=update # Auto-create tables (dev)
spring.datasource.hikari.maximum-pool-size=5 # Connection pool
spring.jpa.show-sql=true # Log SQL (dev)Production Checklist:
- Change JWT secret to strong random value (256-bit minimum)
- Set
spring.jpa.hibernate.ddl-auto=validate - Use Flyway/Liquibase for database migrations
- Enable HTTPS and set
Secureflag on cookies - Update CORS allowed origins to production domains
- Configure proper logging (SLF4J/Logback)
- Set up monitoring (Spring Boot Actuator)
Built with Spring Boot 3.4.8 β’ Java 24 β’ PostgreSQL β’ WebSocket