Skip to main content

Rath Backend Template

This repository holds the boilerplate for the Rath backend. It wraps Spring Boot, the Tranz Technologies rathorm ORM and rath-common utilities to provide a JWT-secured REST API, datagrid helpers and a cacheable select service out of the box.

Table of Contents

  1. Overview
  2. Architecture
  3. Security
  4. Persistence & Schema
  5. Configuration
  6. Running the Application
  7. Public Endpoints
  8. Select Cache Service
  9. Deployment
  10. Development Notes

Overview

  • Spring Boot 4 powers the REST controllers, filters and exception handling.
  • JWT authentication is stored in a secure cookie named rath and refreshed automatically when the token approaches expiration.
  • rathorm + ActiveJDBC manages schema-driven models (User, UserType) and datagrid helpers.
  • Controllers live under com.tranztechnologies.controller, services under service, security helpers under security and security.iam, and error customization in error.

Architecture

LayerPurpose
controllerREST entry points (AuthController, UserController, SelectController).
serviceBusiness logic and data retrieval; SelectService extends RathSelectService and UserService wraps OrmHandler datagrid helpers.
security.iamJWT utilities (JwtTokenUtil, JwtRequestFilter, Authenticator, RathUserDetailsService), cookie-based refresh, and Spring Security wiring via RathSecurityConfiguration.
modelActiveJDBC models that mirror the users and user_types tables.
errorRathErrorAttributes injects the application name and request URL for any /error responses.
rathormRathOrmInitializer seeds User and UserType records during development, wiring into Tranz Technologies tooling (rathorm library).

Security

  • RathSecurityConfiguration disables CSRF, enforces stateless sessions, enables CORS for localhost origins, and wires JwtRequestFilter ahead of the Spring Security filter chain.
  • JwtRequestFilter skips the select/listing endpoints, reads the rath cookie, validates the token, refreshes the cookie when the expiry is within 30 minutes, and populates SecurityContext.
  • Authenticator uses AuthenticationManager and RathUserDetailsService to validate credentials; success writes a JwtResponse to the response cookie.
  • JwtTokenUtil creates and verifies signed tokens, exposes helper methods (validateToken, checkThreshold, construct), and centralizes the shared secret and expiration thresholds.
  • UserUtil exposes the currently logged-in RathUserDetails from the security context for controllers.

Persistence & Schema

  • rathorm.properties (src/main/resources) configures the database connection (jdbc:postgresql://localhost:5432/rath) and scans com.tranztechnologies.model for entities.
  • User maps to users with fields such as username, password, and type_id.
  • UserType maps to user_types with a unique type column.
  • RathOrmInitializer seeds an ADMIN user for smoke testing; run it directly via mvn -pl :backend -DskipTests -Dspring.profiles.active=seed exec:java (or call the main class from your IDE) before using the app on a fresh schema.

Configuration

  • src/main/resources/application.properties currently sets only spring.application.name; replace the placeholder with a meaningful identifier.
  • rathorm.properties must match your PostgreSQL credentials; you can override all rathorm.db.* values with system properties or environment variables when launching the app.
  • JwtTokenUtil.secret and JwtTokenUtil.TOKEN_NAME are hard-coded; rotate the secret and align the cookie name with your frontend security policy before deployment.

Running the Application

  1. Install prerequisites: Java 21+, PostgreSQL (accessible via the JDBC URL in rathorm.properties).
  2. Build: ./mvnw -B -ntp clean package produces a WAR in target/.
  3. Run (development): ./mvnw spring-boot:run picks up application.properties + rathorm.properties.
  4. Database seed: Run com.tranztechnologies.rathorm.RathOrmInitializer once to populate the users and user_types tables, then comment/remove it if you run migrations elsewhere.

Public Endpoints

MethodPathDescription
POST/authenticateJSON payload { "username": "...", "password": "..." }. Authenticates via Authenticator, sets the JWT cookie, and returns user metadata plus roles.
GET/api/authRequires authentication; returns the current user details from UserUtil.
GET/api/usersData grid read for users. Accepts the standard DataGridParams query string (page, size, sort, etc.) handled by OrmHandler.toDataGrid.
GET/api/users/{id}Returns a single user record via OrmHandler.findFirst.
GET/api/select/{key}Delegates to SelectService.cachedSelect to run configured selects (see Select Cache section). Protects every request via the JWT filter except well-known read-only selects.
DELETE/api/select/{key}Drops the cached result set for the requested key.
DELETE/api/selectClears the entire select cache.

Select Cache Service

SelectService extends RathSelectService and registers the users select (id + first_name). Add more cached selects by passing additional SQL entries to the parent constructor.

Deployment

The provided deploy.sh performs a compact deploy:

  1. Builds the project (unless SKIP_BUILD=true).
  2. Copies the generated WAR to /tmp on the remote host via rsync.
  3. Remotes into the host, unpacks the WAR into the configured Tomcat webapps directory, fixes ownership, and optionally restarts Tomcat (RESTART_TOMCAT=true).

Adjust the following environment variables to match your server: REMOTE_HOST, REMOTE_USER, REMOTE_TOMCAT_WEBAPPS, REMOTE_TOMCAT_OWNER, PROJECT_DIR, BUILD_DIR, RESTART_TOMCAT, and SKIP_BUILD.

Development Notes

  1. Keep JwtRequestFilter in sync with any added public endpoints that should bypass authentication (currently /api/select/* and /api/listing/*).
  2. Add new selects/queries through SelectService or new service classes that wrap OrmHandler.
  3. Expand AuthService once you need password resets, registration flows, or integration with external identity providers.
  4. Update rathorm.properties before running integration tests so the test database matches your CI environment.

Feel free to extend this template by adding DTOs, custom exception handlers, or Swagger/OpenAPI metadata as required.