REST API server for a peer-review tracking system (school project data: peers, tasks, checks, friendships). Built on raw Jakarta Servlet API with manual JDBC - no ORM, no Spring.
- Java 17, Jakarta Servlet API 5.0, embedded Tomcat 10.1
- PostgreSQL + HikariCP connection pool
- Jackson (
jackson-datatype-jsr310forLocalDatesupport) - Lombok, JUnit 5, Mockito
- Maven, packaged as WAR (
com.fersko.info.Main)
- No framework, no ORM. All HTTP routing is done via
@WebServletannotations; SQL is written by hand withPreparedStatement. The 4-layer stack (entity - repository - service - servlet) is wired manually via constructors, which makes Mockito injection straightforward. - Generic service/repository interfaces.
BaseRepository<T>andBaseService<T extends BaseDto>define the full CRUD contract once; all 4 entities implement it with zero code duplication in the interface layer. ResponseHandlerutility class centralizes all servlet response logic:handleGetRequest,handleDeleteRequest, andsendJsonResponseare static helpers shared across all 4 servlets, keeping each servlet's HTTP methods to 3-5 lines.- Recursive self-join mapping for
Task.Taskhas a nullableparentTaskof the same type.TaskMapper.toDto()recurses into itself for the parent, andTaskRepositoryImplresolves the join via aLEFT JOIN tasks t1 ON t.parent_task = t1.pk_titlequery with aliased columns (parent_task_title,p_task_xp). - Prefix-based column mapping in
FriendRepositoryImpl. Both peers in afriendsrow are loaded from the sameResultSetusing agetPeer(resultSet, "peer1")/getPeer(resultSet, "peer2")helper that builds column names dynamically from a prefix string. - HikariCP configured statically via
ConnectionManager- pool config is shared across all repository instances via a single staticHikariConfig, with a secondary constructor accepting aHikariDataSourcefor test injection.
# requires PostgreSQL running on localhost:5433, database: postgres
# credentials in src/main/resources/application.properties
psql -U postgres -d postgres -f scriptsSql/tables.sql
./mvnw exec:java -Dexec.mainClass=com.fersko.info.Main
# API available at http://localhost:8080/data/{peers,tasks,checks,friends}
# GET /data/peers?id=1
# POST/PUT /data/checks (JSON body - see DataforTestPostman/)
# DELETE /data/friends?id=3
./mvnw test