Baradum is a powerful library that simplifies filtering and sorting in your Java/Kotlin applications. It allows you to dynamically filter and sort database queries using URL parameters or request body, eliminating the need for complex conditional logic.
- π― Type-Safe Kotlin API: Use property references (
User::name) for compile-time safety - π Enhanced DateFilter: Support for LocalDate, LocalDateTime, java.util.Date, SQL dates with custom patterns
- π’ New Comparison Filters: GreaterFilter and LessFilter with configurable equality
- ποΈ Builder Patterns: Fluent APIs for complex filter configurations
- π Comprehensive Documentation: Complete API reference and migration guides
- π§ Multiple Backend Support: Hefesto (HefestoSQL) and QueryDSL integrations
- Installation
- Module Overview
- Quick Start
- Filter Types
- Kotlin Property References
- Date Filtering
- Sorting
- Body Filtering
- Configuration
- Documentation
- Examples
Baradum is split into multiple modules for flexibility:
| Module | Purpose | Dependencies |
|---|---|---|
| baradum-core | Core filtering/sorting logic | None (standalone) |
| baradum-hefesto | HefestoSQL integration | baradum-core, HefestoSQL |
| baradum-querydsl | QueryDSL integration | baradum-core, QueryDSL 5.0+ |
| apache-tomcat | Spring Boot auto-config | baradum-core, Spring Boot |
| Maven | Gradle |
|---|---|
<!-- Core + Hefesto (Hibernate/HefestoSQL) -->
<dependency>
<groupId>io.github.robertomike</groupId>
<artifactId>baradum-hefesto</artifactId>
<version>3.0.0</version>
</dependency>
<!-- OR QueryDSL (Type-safe queries) -->
<dependency>
<groupId>io.github.robertomike</groupId>
<artifactId>baradum-querydsl</artifactId>
<version>3.0.0</version>
</dependency> |
dependencies {
// Hefesto (Hibernate/HefestoSQL)
implementation 'io.github.robertomike:baradum-hefesto:3.0.0'
// OR QueryDSL (Type-safe queries)
implementation 'io.github.robertomike:baradum-querydsl:3.0.0'
} |
| Maven | Gradle |
|---|---|
<!-- Spring Boot 3 (Jakarta) -->
<dependency>
<groupId>io.github.robertomike</groupId>
<artifactId>baradum-apache-tomcat</artifactId>
<version>3.0.0</version>
</dependency> |
dependencies {
// Spring Boot 3 (Jakarta)
implementation 'io.github.robertomike:baradum-apache-tomcat:3.0.0'
} |
For type-safe queries with QueryDSL 5.0+ and Jakarta Persistence:
| Maven | Gradle |
|---|---|
<dependency>
<groupId>io.github.robertomike</groupId>
<artifactId>baradum-querydsl</artifactId>
<version>3.0.0</version>
</dependency> |
dependencies {
implementation 'io.github.robertomike:baradum-querydsl:3.0.0'
} |
Features:
- β Full QueryDSL integration with type-safe queries
- β
Extension functions for Q-classes:
QUser.user.baradum(em) - β Jakarta Persistence (JPA 3.0+) support
- β 11.76x performance boost with global caching
- β Comprehensive test coverage (90+ tests)
Quick Example:
val users = QUser.user
.baradum(entityManager)
.allowedFilters(
ExactFilter(User::name),
GreaterFilter(User::age, orEqual = true)
)
.withParams(request.parameterMap)
.get()See baradum-querydsl/README.md for complete documentation.
| Module | Coverage | Tests | Status |
|---|---|---|---|
| baradum-core | 83.8% | 327 tests | β Excellent |
| baradum-hefesto | 82.7% | 198 tests | β Excellent |
| baradum-querydsl | 74.1% | 91 tests | β Good |
| Overall | 80.9% | 616 tests | β Very Good |
All core functionality is thoroughly tested with unit and integration tests.
Without Baradum (Traditional Approach):
@GetMapping("/users")
public List<User> getUsers(
@RequestParam(required = false) Long categoryId,
@RequestParam(required = false) Integer minAge,
@RequestParam(required = false) Integer maxAge
) {
if (categoryId != null && minAge != null && maxAge != null) {
return repository.findByCategoryIdAndAgeGreaterThanEqualAndAgeLessThanEqual(
categoryId, minAge, maxAge
);
}
if (categoryId != null && minAge != null) {
return repository.findByCategoryIdAndAgeGreaterThanEqual(categoryId, minAge);
}
if (minAge != null && maxAge != null) {
return repository.findByAgeGreaterThanEqualAndAgeLessThanEqual(minAge, maxAge);
}
// ... 5 more conditional branches
return repository.findAll();
}With Baradum:
@GetMapping("/users")
public List<User> getUsers() {
return Baradum.make(User.class)
.allowedFilters("categoryId")
.allowedFilters(new IntervalFilter("age"))
.page();
}Kotlin with Type Safety:
@GetMapping("/users")
fun getUsers(): List<User> {
return Baradum.make(User::class.java)
.allowedFilters(
ExactFilter(User::categoryId),
IntervalFilter(User::age)
)
.page()
}URL Usage:
?categoryId=2β Filters bycategoryId = 2?age=18-65β Filters byage >= 18 AND age <= 65?categoryId=2&age=18-65β Both filters applied
| Filter | Purpose | Example URL | SQL Result |
|---|---|---|---|
| ExactFilter | Exact matching | ?status=ACTIVE |
status = 'ACTIVE' |
| PartialFilter | LIKE search | ?name=john |
name LIKE 'john%' |
| SearchFilter | Multi-field OR | ?search=john |
name LIKE '%john%' OR email LIKE '%john%' |
| EnumFilter | Enum values | ?status=ACTIVE,PENDING |
status IN ('ACTIVE', 'PENDING') |
| IntervalFilter | Numeric ranges | ?age=18-65 |
age >= 18 AND age <= 65 |
| InFilter | Multiple values | ?country=US,CA,MX |
country IN ('US', 'CA', 'MX') |
| IsNullFilter | NULL checks | ?deletedAt=null |
deletedAt IS NULL |
| Filter | Purpose | Example URL | SQL Result |
|---|---|---|---|
| ComparisonFilter | Flexible operators | ?price=>100 |
price > 100 |
| GreaterFilter | Greater than | ?age=18 |
age > 18 or age >= 18 |
| LessFilter | Less than | ?age=65 |
age < 65 or age <= 65 |
| Filter | Purpose | Example URL | SQL Result |
|---|---|---|---|
| DateFilter | Date filtering | ?date=2024-01-01|2024-12-31 |
date BETWEEN '2024-01-01' AND '2024-12-31' |
| Comparison | ?date=>2024-01-01 |
date > '2024-01-01' |
| Filter | Purpose | Example | Description |
|---|---|---|---|
| CustomFilter | Lambda logic | See docs | Custom filtering logic |
Use Kotlin property references for compile-time safety:
data class User(
val id: Long,
val name: String,
val email: String,
val age: Int,
val status: Status,
val createdAt: LocalDateTime
)
@GetMapping("/users")
fun getUsers(): List<User> {
return Baradum.make(User::class.java)
.allowedFilters(
ExactFilter(User::id), // ?id=123
PartialFilter(User::name, "search"), // ?search=john
EnumFilter(User::status, Status::class.java), // ?status=ACTIVE
IntervalFilter(User::age), // ?age=18-65
DateFilter.forLocalDateTime(User::createdAt), // ?createdAt=>2024-01-01
GreaterFilter(User::age, "minAge", orEqual = true), // ?minAge=18
LessFilter(User::age, "maxAge", orEqual = true) // ?maxAge=65
)
.allowedSort(User::name, User::createdAt)
.page()
}Benefits:
- β Compile-time field validation
- β Refactoring support
- β IDE auto-completion
- β Type safety
// LocalDate (default)
DateFilter("createdAt")
// LocalDateTime with custom pattern
DateFilter.forLocalDateTime("updatedAt", "dd/MM/yyyy HH:mm:ss")
// java.util.Date
DateFilter.forUtilDate("birthDate", "MM-dd-yyyy")
// SQL Date
DateFilter.forSqlDate("startDate")
// SQL Timestamp
DateFilter.forSqlTimestamp("eventTime")
// Builder pattern
DateFilter.builder("eventDate")
.useLocalDate()
.withPattern("yyyy/MM/dd")
.build()| URL Parameter | SQL Result |
|---|---|
?date=2024-01-01 |
date = '2024-01-01' |
?date=2024-01-01|2024-12-31 |
date >= '2024-01-01' AND date <= '2024-12-31' |
?date=>2024-01-01 |
date > '2024-01-01' |
?date=>=2024-01-01 |
date >= '2024-01-01' |
?date=<2024-12-31 |
date < '2024-12-31' |
?date=<=2024-12-31 |
date <= '2024-12-31' |
return Baradum.make(User.class)
.allowedSort("name", "createdAt")
.get();URL Examples:
?sort=nameβORDER BY name ASC?sort=-nameβORDER BY name DESC?sort=name,-createdAtβORDER BY name ASC, createdAt DESC
.allowedSort(new OrderBy("alias", "actual_field_name")).allowedSort(User::name, User::createdAt, User::email)For complex filtering scenarios, use JSON body:
{
"filters": [
{
"field": "id",
"value": "1",
"operator": "EQUAL"
},
{
"field": "name",
"value": "abc%",
"operator": "LIKE",
"type": "OR"
},
{
"field": "status",
"operator": "IS_NULL",
"type": "AND"
},
{
"subFilters": [
{
"field": "status",
"value": "ACTIVE,INACTIVE",
"operator": "IN",
"type": "OR"
}
]
}
],
"sorts": [
{
"field": "id"
},
{
"field": "name",
"sort": "DESC"
}
]
}No configuration needed! Spring Boot 2 & 3 are auto-configured.
public class BaradumConfig {
@Bean
public void configureBaradum(HttpServletRequest request) {
// For Apache Tomcat 9 (Spring Boot 2)
new AutoConfigurationSpring2(request);
// For Apache Tomcat 10 (Spring Boot 3)
new AutoConfigurationSpring3(request);
}
}public class MyCustomRequest extends BasicRequest<HttpServletRequest> {
public MyCustomRequest(HttpServletRequest request) {
super(request);
}
@Override
public String findParamByName(String name) {
return getRequest().getParameter(name);
}
@Override
public String getMethod() {
return getRequest().getMethod();
}
@Override
public BufferedReader getReader() throws IOException {
return getRequest().getReader();
}
}
// Configure Baradum
Baradum.setRequest(new MyCustomRequest(request));- Complete Documentation - Full guide with examples
- Filter API Reference - Detailed filter documentation
- Migration Guide - Upgrade from previous versions
- Test Suite Summary - Test coverage details
@GetMapping("/products")
fun getProducts(): Page<Product> {
return Baradum.make(Product::class.java)
.allowedFilters(
ExactFilter(Product::category),
PartialFilter(Product::name, "search"),
GreaterFilter(Product::price, "minPrice", orEqual = true),
LessFilter(Product::price, "maxPrice", orEqual = true),
EnumFilter(Product::status, ProductStatus::class.java),
InFilter(Product::brand, "brands")
)
.allowedSort(Product::price, Product::name)
.page()
}Usage:
GET /products?category=electronics&search=laptop&minPrice=500&maxPrice=2000
&brands=Apple,Dell,HP&status=IN_STOCK&sort=price
@GetMapping("/users")
public List<User> getUsers() {
return Baradum.make(User.class)
.allowedFilters(
PartialFilter("username"),
SearchFilter.of("search", "username", "email", "fullName"),
EnumFilter("role", Role.class),
DateFilter.forLocalDateTime("createdAt"),
IntervalFilter("age"),
IsNullFilter("deletedAt")
)
.allowedSort("username", "createdAt")
.get();
}Usage:
GET /users?search=john&role=ADMIN&age=25-50&deletedAt=null&sort=-createdAt
@GetMapping("/events")
public List<Event> getEvents() {
return Baradum.make(Event.class)
.allowedFilters(
ExactFilter("organizerId"),
PartialFilter("title"),
DateFilter.builder("eventDate")
.useLocalDateTime()
.withPattern("yyyy-MM-dd HH:mm")
.build(),
GreaterFilter("attendeeCount", "minAttendees", true),
InFilter("location")
)
.allowedSort("eventDate", "title")
.page();
}Usage:
GET /events?title=concert&eventDate=>2024-01-01&minAttendees=100
&location=NY,LA,CHI&sort=eventDate
ExactFilter("status").setDefaultValue("ACTIVE")IntervalFilter("age").addIgnore("0", "null", "")new CustomFilter<>("status", (query, value) -> {
if (value.equals("premium")) {
query.where("subscription_level", BaradumOperator.GREATER, 5);
} else {
query.where("status", BaradumOperator.EQUAL, value);
}
})- Swagger/OpenAPI: Manual documentation required (no auto-generation support)
- Spring Boot: Versions 2 & 3 supported
- Apache Tomcat: Versions 9 & 10 supported
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE.txt file for details.
If you find this library helpful, consider buying me a coffee!
Made with β€οΈ by Roberto Mike
