A Spring Boot application demonstrating production-ready features including JPA auditing, Hibernate Envers, RestClient for third-party API integration, structured logging with Logback, Spring Boot Actuator for monitoring, and OpenAPI/Swagger for API documentation.
| Feature | Description |
|---|---|
| JPA Auditing | Auto-managed createdBy, createdDate, updatedBy, updatedDate fields |
| Hibernate Envers | Full revision history and audit trail for entities |
| RestClient | Type-safe HTTP client for third-party API integration |
| Logging | Structured logging with SLF4J, Logback and log levels |
| Spring Boot Actuator | Health checks, metrics and monitoring endpoints |
| OpenAPI/Swagger | Auto-generated API documentation |
| DevTools | Hot reload for faster development |
AuditableEntity— base class with@CreatedDate,@LastModifiedDate,@CreatedBy,@LastModifiedByAuditorAwareImpl— provides current user for auditingPostEntity— extendsAuditableEntitywith@Auditedfor revision historyAuditController—/audit/posts/{postId}endpoint to fetch full revision history
EmployeeClient— interface defining Employee API operationsEmployeeClientImpl— RestClient implementation with error handling and loggingRestClientConfig— configures RestClient with base URL and default headers- Supports GET, POST operations with
4xxand5xxerror handling
- SLF4J with Logback — structured logging across all layers
- Log levels —
TRACE,DEBUG,INFO,ERRORused appropriately logback-spring.xml— rolling file appender with size and time based policy- Package-level log configuration in
application.properties
- All endpoints exposed —
management.endpoints.web.exposure.include=* - Info endpoints — app version, build info, git info, Java and OS details
- Health checks available at
/actuator/health
- Auto-generated API documentation
- Available at
http://localhost:9000/swagger-ui.html - API specs at
http://localhost:9000/v3/api-docs
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
@Audited
public class AuditableEntity {
@CreatedDate
private LocalDateTime createdDate;
@LastModifiedDate
private LocalDateTime updatedDate;
@CreatedBy
private String createdBy;
@LastModifiedBy
private String updatedBy;
}@GetMapping(path = "/audit/posts/{postId}")
List<PostEntity> getPostRevisions(@PathVariable Long postId) {
AuditReader reader = AuditReaderFactory.get(entityManagerFactory.createEntityManager());
List<Number> revisions = reader.getRevisions(PostEntity.class, postId);
return revisions.stream()
.map(rev -> reader.find(PostEntity.class, postId, rev))
.collect(Collectors.toList());
}ApiResponse<List<EmployeeDTO>> response = restClient.get()
.uri("employees")
.retrieve()
.onStatus(HttpStatusCode::is4xxClientError, (req, res) -> {
throw new ResourceNotFoundException("Employee not found");
})
.body(new ParameterizedTypeReference<>() {});log.trace("Trying to retrieve all employees");
log.info("Attempting to call restClient");
log.debug("Successfully retrieved employees");
log.error("Exception occurred", e);| Method | Endpoint | Description |
|---|---|---|
GET |
/posts |
Get all posts |
GET |
/posts/{postId} |
Get post by ID |
POST |
/posts |
Create new post |
PUT |
/posts/{postId} |
Update post |
GET |
/audit/posts/{postId} |
Get post revision history |
GET |
/actuator/health |
Application health check |
GET |
/actuator/info |
Application info |
GET |
/swagger-ui.html |
Swagger UI |
Prerequisites: Java 21+, Maven, MySQL
git clone https://github.com/MansiArora-dev/prod-ready-features.git
cd prod-ready-featuresSetup MySQL:
- Create database:
CREATE DATABASE <your_database_name>; - Create
application-local.propertiesinsrc/main/resources/with your credentials:
spring.datasource.url=jdbc:mysql://localhost:3306/<your_database_name>?useSSL=false
spring.datasource.username=<your_username>
spring.datasource.password=<your_password>
⚠️ Addapplication-local.propertiesto.gitignoreto avoid committing credentials
Using IntelliJ IDEA (Recommended):
- Open project in IntelliJ
- Run → Edit Configurations
- Environment variables:
SPRING_PROFILES_ACTIVE=local - Click Run
▶️
Using Maven:
mvn spring-boot:run -Dspring-boot.run.profiles=localsrc/main/java/com/springboot/prodreadyfeatures/
├── advice/
│ ├── ApiError.java # Error response structure
│ ├── ApiResponse.java # Generic response wrapper
│ └── GlobalExceptionHandler.java # Centralized exception handling
├── auth/
│ └── AuditorAwareImpl.java # Current user provider for auditing
├── clients/
│ ├── impl/
│ │ └── EmployeeClientImpl.java # RestClient implementation
│ └── EmployeeClient.java # Employee API client interface
├── config/
│ ├── AppConfig.java # JPA auditing + ModelMapper config
│ └── RestClientConfig.java # RestClient bean configuration
├── controllers/
│ ├── AuditController.java # Revision history endpoints
│ └── PostController.java # Post CRUD endpoints
├── dto/
│ ├── EmployeeDTO.java # Employee data transfer object
│ └── PostDTO.java # Post data transfer object
├── entities/
│ ├── AuditableEntity.java # Base auditing entity
│ └── PostEntity.java # Post entity with audit support
├── exceptions/
│ └── ResourceNotFoundException.java # Custom runtime exception
├── repositories/
│ └── PostRepository.java # JPA Repository
└── services/
├── impl/
│ └── PostServiceImpl.java # Post service implementation
└── PostService.java # Post service interface
src/main/resources/
├── application.properties # App configuration
└── logback-spring.xml # Logback configuration
- Java 21 | Spring Boot | Maven
- Spring Data JPA | MySQL
- Spring Boot Actuator | Hibernate Envers | SpringDoc OpenAPI
- JPA Auditing — Auto-tracks who created/modified records and when
- Hibernate Envers — Complete revision history without manual tracking
- RestClient — Modern, fluent API for HTTP calls with proper error handling
- Structured Logging — Different log levels for different environments
- Actuator — Production monitoring without extra code
- OpenAPI — Auto-generated, always up-to-date API documentation
Mansi Arora — Software Engineer