A reusable template for building scalable REST APIs with Spring Boot.
This project provides a clean, layered architecture that follows best practices for structuring enterprise-grade backend services.
- Standardized Spring Boot project structure
- Clear separation of concerns using layered architecture
- Ready-to-use DTOs, Mappers, and Exception Handling
- Configurable application setup
- Entity auditing with Hibernate Envers
- API audit logging with MongoDB (tracks all API requests and responses)
- Spring Security integration
- Bean validation for request data
- Development and production profiles
- Easily extendable for any backend service
eg.com.company.projectname
β
βββ controller # Handles HTTP requests & responses (@RestController)
βββ service # Business logic & workflows (@Service)
βββ repository # Data persistence & CRUD operations (@Repository)
βββ model
β βββ entity # JPA entities mapped to DB tables
β βββ dto # Data Transfer Objects (API contracts)
βββ mapper # Converts Entities <-> DTOs (MapStruct / manual)
βββ config # Application-wide configurations (@Configuration)
βββ exception # Custom exceptions & global exception handler
βββ utilities # Helper classes for common reusable functions
βββ Application.java # Main Spring Boot entry point
- Receives HTTP requests, validates input, and delegates to the Service layer.
- Annotated with
@RestController. - Rule: No business logic here, only request/response handling.
- Core business logic and rules live here.
- Annotated with
@Serviceand often@Transactional. - Orchestrates repository calls and integrates with external services.
- Responsible for data persistence.
- Annotated with
@Repository, typically extendsJpaRepositoryorCrudRepository.
- Entity: Database-mapped domain objects annotated with
@Entityand@Audited. - DTO: Data Transfer Objects with validation annotations to safely expose only required data.
- Converts between Entities and DTOs.
- Can use MapStruct or manual mapping.
- Beans, security, and application-wide setup (
@Configuration).
- Stateless helper classes (e.g., date handling, string formatting, validation).
- Centralized error handling with
@ControllerAdvice. - Custom exceptions (e.g.,
UserNotFoundException). - Provides consistent error responses with proper HTTP status codes.
- Validation error handling for request data.
- Java 23
- Spring Boot 3.5.5
- Spring Data JPA
- Spring Security
- PostgreSQL (database)
- MapStruct 1.5.5.Final (for mapping Entities β DTOs)
- Lombok 1.18.30 (for boilerplate reduction)
- Hibernate Envers (for entity auditing)
- Maven (build tool)
- Java 23
- Maven 3.9+
- PostgreSQL database
- GitHub Desktop or Git CLI
git clone https://github.com/your-username/spring-boot-rest-api-template.git
cd spring-boot-rest-api-templateCreate a PostgreSQL database named restapi (or update the application.properties file with your database name).
mvn spring-boot:runmvn spring-boot:run -Dspring.profiles.active=devThe API will be available at:
π http://localhost:8080/api/v1
GET /api/v1/usersβ Get all usersPOST /api/v1/usersβ Create a userGET /api/v1/users/{id}β Get user by IDPUT /api/v1/users/{id}β Update userDELETE /api/v1/users/{id}β Delete user
GET /api/v1/audit-logsβ Get all audit logs (paginated)GET /api/v1/audit-logs/{id}β Get audit log by IDGET /api/v1/audit-logs/action/{action}β Get audit logs by actionGET /api/v1/audit-logs/endpoint/{endpoint}β Get audit logs by endpointGET /api/v1/audit-logs/method/{method}β Get audit logs by HTTP methodGET /api/v1/audit-logs/status/{status}β Get audit logs by statusGET /api/v1/audit-logs/date-rangeβ Get audit logs by date rangeGET /api/v1/audit-logs/statsβ Get audit statistics
(You can adjust these according to your project needs.)
This project includes a comprehensive API audit logging system using MongoDB to track all API requests and responses.
- Automatic logging of API requests and responses
- Captures HTTP method, endpoint, client IP, request/response payloads
- Tracks success/failure status of each request
- Records authenticated user who made the request
- Timestamps for all audit events
- Custom annotation
@AuditableApito mark methods for audit logging
- Add the annotation to your controller methods:
@RestController
@RequestMapping("/api/v1/users")
public class UserController {
@GetMapping
@AuditableApi(action = "get_all_users") // Define a descriptive action name
public ResponseEntity<List<UserDto>> getAllUsers() {
// Your controller logic
return ResponseEntity.ok(users);
}
@GetMapping("/{id}")
@AuditableApi(action = "get_user_by_id") // Action for retrieving a specific user
public ResponseEntity<UserDto> getUserById(@PathVariable Long id) {
// Your controller logic
return ResponseEntity.ok(user);
}
@PostMapping
@AuditableApi(action = "create_user") // Action for user creation
public ResponseEntity<UserDto> createUser(@Valid @RequestBody UserDto userDto) {
// Your controller logic
return ResponseEntity.status(HttpStatus.CREATED).body(createdUser);
}
@PutMapping("/{id}")
@AuditableApi(action = "update_user") // Action for user update
public ResponseEntity<UserDto> updateUser(@PathVariable Long id, @Valid @RequestBody UserDto userDto) {
// Your controller logic
return ResponseEntity.ok(updatedUser);
}
@DeleteMapping("/{id}")
@AuditableApi(action = "delete_user") // Action for user deletion
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
// Your controller logic
return ResponseEntity.noContent().build();
}
}- Access audit logs via the API endpoints:
GET /api/v1/audit-logs # Get all logs (paginated)
GET /api/v1/audit-logs/stats # Get usage statistics- Filter audit logs:
GET /api/v1/audit-logs/action/create_user # Filter by action
GET /api/v1/audit-logs/status/FAILED # View only failed requests- Best practices for
@AuditableApiannotation:
- Use consistent action naming conventions: Prefer lowercase with underscores (e.g.,
get_user,create_order) - Be descriptive but concise: Action names should clearly indicate what operation is being performed
- Group related actions: Use prefixes for related operations (e.g.,
user_create,user_update,user_delete) - Apply to all sensitive operations: Especially those involving data creation, modification, or deletion
- Consider security implications: Ensure sensitive data is properly masked in request/response payloads
- Uses Spring AOP for non-intrusive request/response interception
- MongoDB for scalable, schema-flexible storage
- Asynchronous logging to minimize performance impact
- Configurable via application.properties
This project implements Optimistic Concurrency Control (OCC) to handle concurrent updates to the same database record without locking it.
Optimistic Concurrency Control (OCC) is a strategy used to handle concurrent updates to the same database record without locking it.
- The assumption: conflicts are rare.
- Each transaction works on its own copy of data, and before committing, it checks if the data has been modified by someone else.
- If another transaction modified it β a conflict occurs β an exception (e.g.,
OptimisticLockException) is raised, and you decide how to resolve it (retry, reject, merge, etc.).
This template implements optimistic locking using Hibernate's @Version annotation:
@MappedSuperclass
public abstract class AuditableEntity {
// Other fields...
@Version // π Concurrency check attribute
@Column(name = "version", nullable = false)
private Long version; // Hibernate handles this automatically
}- Version Tracking: Each entity has a version field that Hibernate automatically increments on each update.
- Conflict Detection: When updating an entity, Hibernate checks if the version in the database matches the version when the entity was loaded.
- Exception Handling: If versions don't match (meaning someone else updated the record), an
OptimisticLockExceptionis thrown.
- No Database Locks: Improves performance by avoiding database locks
- Better Scalability: Allows more concurrent operations
- Conflict Resolution: Provides clear mechanism for handling conflicts
- Data Integrity: Prevents the "lost update" problem where one user's changes overwrite another's
- Handle
OptimisticLockExceptiongracefully in your service layer - Consider implementing retry mechanisms for non-critical operations
- Provide clear feedback to users when conflicts occur
- Use optimistic locking for entities that are frequently read but rarely updated concurrently
This project is licensed under the MIT License β see the LICENSE file for details.
Contributions are welcome! Please fork this repo and submit a pull request.