Spring Boot CrudX Framework
Complete API Documentation
CrudX is a powerful Spring Boot framework that automatically generates production-ready REST APIs with zero boilerplate code. Built for developers who value rapid development without sacrificing control or customization.
Quick Setup
Get started with CrudX in under 5 minutes
5 Steps to Your First API
Add Dependencies
Add CrudX to your project using Gradle or Maven
Gradle (build.gradle)
dependencies {
implementation 'io.github.sachinnimbal:crudx-starter:1.0.1'
// Choose your database
runtimeOnly 'com.mysql:mysql-connector-j'
// OR runtimeOnly 'org.postgresql:postgresql'
// OR implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
}
Maven (pom.xml)
<dependency>
<groupId>io.github.sachinnimbal</groupId>
<artifactId>crudx-starter</artifactId>
<version>1.0.1</version>
</dependency>
<!-- Add database driver -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
Enable CrudX
Add @CrudX annotation to your Spring Boot application class
@SpringBootApplication
@CrudX // 👈 Add this annotation
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
What happens behind the scenes:
- Scans for CrudX controllers and entities
- Auto-generates repositories and services
- Configures database connections
- Enables REST endpoint generation
Configure Database
Add database configuration to application.yml or application.properties
MySQL Configuration
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: root
password: password
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: update
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL8Dialect
PostgreSQL Configuration
spring:
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: postgres
password: password
jpa:
properties:
hibernate:
dialect: org.hibernate.dialect.PostgreSQLDialect
MongoDB Configuration
spring:
data:
mongodb:
uri: mongodb://localhost:27017/mydb
database: mydb
Create Your Entity
Extend the appropriate CrudX base class for your database
import io.github.sachinnimbal.crudx.entity.CrudXMySQLEntity;
import jakarta.persistence.*;
import lombok.Data;
@Entity
@Table(name = "employees")
@Data
public class Employee extends CrudXMySQLEntity<Long> {
@Column(nullable = false)
private String name;
@Column(unique = true, nullable = false)
private String email;
private String department;
private Double salary;
}
Choose the right base class:
-
CrudXMySQLEntity<ID>- For MySQL/MariaDB -
CrudXPostgreSQLEntity<ID>- For PostgreSQL -
CrudXMongoEntity<ID>- For MongoDB
Create Controller
Extend CrudXController - that's it! No additional code needed.
import io.github.sachinnimbal.crudx.controller.CrudXController;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/employees")
public class EmployeeController extends CrudXController<Employee, Long> {
// That's it! 11 REST endpoints are auto-generated:
// POST /api/employees - Create single
// POST /api/employees/batch - Create batch
// GET /api/employees - Get all
// GET /api/employees/paged - Get paginated
// GET /api/employees/{id} - Get by ID
// PATCH /api/employees/{id} - Partial update
// DELETE /api/employees/{id} - Delete by ID
// DELETE /api/employees/batch - Delete batch
// GET /api/employees/count - Count all
// GET /api/employees/exists/{id} - Check existence
// Add custom endpoints or lifecycle hooks here (optional)
}
You're All Set!
Your API is now ready! Start your application and test the endpoints:
http://localhost:8080/api/employees
http://localhost:8080/api/employees
http://localhost:8080/swagger-ui/index.html
Swagger UI
Core Annotations
@CrudX
Since v1.0.0Enables CrudX framework functionality in your Spring Boot application.
Target: Application Class
@SpringBootApplication
@CrudX
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
What it does:
- Automatically scans for CrudX controllers
- Registers service beans for detected entities
- Configures database connections
- Enables auto-repository generation
- Initializes performance monitoring
@CrudXUniqueConstraints
Container annotation for defining multiple unique constraints on an entity.
| Attribute | Type | Required | Description |
|---|---|---|---|
value |
@CrudXUniqueConstraint[] | Yes | Array of unique constraint definitions |
@Entity
@CrudXUniqueConstraints({
@CrudXUniqueConstraint(
fields = {"email"},
message = "Email already registered"
),
@CrudXUniqueConstraint(
fields = {"username"},
message = "Username already taken"
),
@CrudXUniqueConstraint(
fields = {"phoneNumber"},
message = "Phone number already registered"
)
})
public class User extends CrudXMySQLEntity<Long> {
private String email;
private String username;
private String phoneNumber;
}
What it does:
- Groups multiple unique constraints on a single entity
- Validates each constraint independently during create/update operations
- Returns specific error messages for each violated constraint
- Prevents duplicate entries across multiple field combinations
- Automatically generates database-level unique indexes
@CrudXUniqueConstraint
Defines a unique constraint on one or more fields.
| Attribute | Type | Required | Description |
|---|---|---|---|
fields |
String[] | Yes | Field names that must be unique |
name |
String | No | Constraint name (optional) |
message |
String | No | Custom error message |
@Entity
@CrudXUniqueConstraint(
fields = {"email"},
message = "Email address already exists"
)
public class User extends CrudXMySQLEntity<Long> {
private String email;
}
What it does:
- Enforces uniqueness on specified field(s) at application level
- Validates before insert/update operations to prevent duplicates
- Supports single or composite field uniqueness
- Returns custom error message when constraint is violated
- Creates corresponding database unique index automatically
@CrudXImmutable
New v1.0.1Marks a field as immutable - cannot be updated after entity creation.
@Entity
public class Employee extends CrudXMySQLEntity<Long> {
@CrudXImmutable(message = "Employee code cannot be changed")
private String employeeCode;
@CrudXImmutable(message = "Hire date is permanent")
private LocalDate hireDate;
private String name; // Can be updated
}
Validation Behavior:
- Automatically enforced on PATCH operations
- Throws IllegalArgumentException if update attempted
- Works alongside Bean Validation annotations
- Zero configuration required
Base Entity Classes
CrudXMySQLEntity<ID>
Base class for MySQL entities with auto-increment ID generation.
GenerationType.IDENTITY
@Entity
@Table(name = "employees")
public class Employee extends CrudXMySQLEntity<Long> {
@Column(nullable = false)
private String name;
@Column(unique = true)
private String email;
private String department;
private BigDecimal salary;
}
CrudXPostgreSQLEntity<ID>
Base class for PostgreSQL entities with sequence-based ID generation.
GenerationType.SEQUENCE
@Entity
@Table(name = "products")
public class Product extends CrudXPostgreSQLEntity<Long> {
private String name;
private String sku;
private BigDecimal price;
private Integer stock;
}
CrudXMongoEntity<ID>
Base class for MongoDB documents with flexible schema.
@Document(collection = "users")
public class User extends CrudXMongoEntity<String> {
private String username;
private String email;
private List<String> roles;
private Map<String, Object> metadata;
}
Auto-Generated REST Endpoints
11 production-ready endpoints generated automatically
/api/{resource}
Create Single Entity
Creates a new entity in the database.
Request Body:
{
"name": "CrudX Starter",
"email": "crudx@example.com",
"department": "Engineering"
}
Response (201):
{
"success": true,
"statusCode": 201,
"data": {
"id": 1,
"name": "CrudX Starter"
}
}
/api/{resource}/batch
Enhanced v1.0.1
Create Batch
Creates multiple entities at once with intelligent chunking.
Key Features:
- Batch Limit: Max 100,000 records per request
- Intelligent Chunking: Auto-processes in 500-record chunks
- Progress Tracking: Real-time logs for large batches
- Memory Optimized: Efficient processing
| Parameter | Type | Default | Description |
|---|---|---|---|
skipDuplicates |
boolean | true | Skip duplicate entries instead of failing |
/api/{resource}/{id}
Get by ID
Retrieves a single entity by its ID.
/api/{resource}
Get All (Auto-Paginated)
Retrieves all entities with automatic pagination for large datasets (>1000).
Auto-Pagination:
When total records exceed 1000, CrudX automatically returns a paginated response with the first 1000 records and pagination metadata.
/api/{resource}/paged
Get Paginated
Retrieves entities with custom pagination parameters.
| Parameter | Type | Default | Description |
|---|---|---|---|
page |
int | 0 | Page number (0-indexed) |
size |
int | 10 | Items per page (max: 100,000) |
sortBy |
String | - | Field to sort by |
sortDirection |
String | ASC | Sort direction (ASC/DESC) |
/api/{resource}/{id}
Enhanced v1.0.1
Partial Update
Updates specific fields of an entity with smart validation.
Smart Validation (Zero Config):
- Auto-Protected: id, createdAt, createdBy
- Immutable Fields: @CrudXImmutable enforced
- Bean Validation: @Email, @Size, @NotNull
- Unique Constraints: @CrudXUniqueConstraint validated
{
"department": "Management",
"salary": 95000
}
/api/{resource}/{id}
Delete by ID
Deletes a single entity by its ID.
/api/{resource}/batch
Delete Batch
Deletes multiple entities by their IDs (max 1000 per request).
/api/{resource}/count
Count
Returns the total count of entities.
/api/{resource}/exists/{id}
Check Existence
Checks if an entity exists with the given ID.
Service Layer API
Access auto-generated services for custom operations
CrudXService Interface
public interface CrudXService<T, ID> {
// CREATE
T create(T entity);
BatchResult<T> createBatch(List<T> entities, boolean skipDuplicates);
// READ
T findById(ID id);
List<T> findAll();
Page<T> findAll(Pageable pageable);
// UPDATE
T update(ID id, Map<String, Object> updates);
// DELETE
void delete(ID id);
BatchResult<ID> deleteBatch(List<ID> ids);
// UTILITY
long count();
boolean existsById(ID id);
}
Using Service in Custom Logic
@GetMapping("/department/{dept}")
public ResponseEntity<List<Employee>> getByDepartment(
@PathVariable String dept) {
List<Employee> all = crudService.findAll();
List<Employee> filtered = all.stream()
.filter(e -> dept.equals(e.getDepartment()))
.collect(Collectors.toList());
return ResponseEntity.ok(filtered);
}
Configuration
Database Configuration
MySQL
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: ${DB_USERNAME:root}
password: ${DB_PASSWORD:password}
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: update
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL8Dialect
PostgreSQL
spring:
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: ${DB_USERNAME:postgres}
password: ${DB_PASSWORD:password}
jpa:
properties:
hibernate:
dialect: org.hibernate.dialect.PostgreSQLDialect
MongoDB
spring:
data:
mongodb:
uri: mongodb://localhost:27017/mydb
database: mydb
CrudX Configuration
crudx:
database:
auto-create: true # Auto-create database if not exists
performance:
enabled: false # Enable performance monitoring
dashboard-enabled: true
dashboard-path: /crudx/performance
swagger:
enabled: true # Enable Swagger UI
Performance Monitoring
Real-time request monitoring and analytics
Enable Monitoring
crudx:
performance:
enabled: true
Dashboard Access:
http://localhost:8080/crudx/performance/dashboard
Key Features
Real-time Monitoring
Track metrics as they happen
Response Time Charts
Visualize performance
Success/Failure Rates
Monitor API reliability
Memory Analytics
Track resource usage
Error Handling
Error Codes
| Code | HTTP Status | Description |
|---|---|---|
ENTITY_NOT_FOUND |
404 | Entity not found with given ID |
DUPLICATE_ENTITY |
409 | Unique constraint violation |
VALIDATION_ERROR |
400 | Bean validation failed |
INVALID_ARGUMENT |
400 | Invalid request parameter |
DATABASE_ERROR |
500 | Database operation failed |
Error Response Format
{
"success": false,
"message": "Email address already exists",
"statusCode": 409,
"status": "CONFLICT",
"error": {
"code": "DUPLICATE_ENTITY",
"details": "Duplicate entry for unique constraint"
},
"timestamp": "2025-01-15T16:00:00"
}
Advanced Features
🏢 Multi-Tenancy
Isolate data by tenant with automatic filtering.
@Entity
@Where(clause = "tenant_id = current_tenant()")
public class Employee extends CrudXMySQLEntity<Long> {
@Column(name = "tenant_id")
private String tenantId;
}
🗑️ Soft Delete
Mark records as deleted without removing them.
@Override
protected void beforeDelete(Long id, Employee entity) {
entity.setDeleted(true);
crudService.update(id, Map.of("deleted", true));
throw new PreventDeletionException();
}
📡 Event Publishing
Publish domain events for reactive architectures.
@Override
protected void afterCreate(Employee entity) {
eventPublisher.publishEvent(
new EmployeeCreatedEvent(this, entity)
);
}
⚡ Caching
Speed up reads with Spring Cache abstraction.
@Override
@Cacheable(key = "#id")
protected void afterFindById(Employee entity) {
// Entity cached after retrieval
}
Best Practices
✅ Entity Design
- • Add @CrudXUniqueConstraint for unique fields
- • Use appropriate ID types (Long for SQL)
- • Add JPA indexes for frequent queries
- • Keep entities focused and normalized
✅ Controller Design
- • Use lifecycle hooks for cross-cutting concerns
- • Don't override auto-generated endpoints
- • Add custom endpoints for specific logic
- • Use @PreAuthorize for security
✅ Performance
- • Always use pagination for large datasets
- • Add database indexes for sort/filter fields
- • Use batch operations for bulk processing
- • Enable performance monitoring in dev
✅ Validation
- • Use @CrudXImmutable for permanent fields
- • Combine Bean Validation annotations
- • Add @CrudXUniqueConstraint for unique fields
- • Let CrudX auto-validate - no manual code
Pro Tip
Start with CrudX's auto-generated endpoints and only add custom logic through lifecycle hooks when needed. This keeps your codebase clean and maintainable while giving you full control when necessary.