Query Filter Builder is a robust and versatile library designed to dynamically generate type-safe JPA queries from HTTP query parameters in Spring Boot applications.
- Overview
- Features
- Requirements
- Installation
- Quick Start
- Query Parameter Format
- Supported Operators
- Supported Types
- Error Handling
- Contributing
- License
Query Filter Builder simplifies the process of dynamically filtering data in Spring Boot applications by converting HTTP query parameters into type-safe JPA predicates. It eliminates the complexity of manually writing filtering logic while maintaining clean and maintainable code.
- 🚀 Automatic Conversion: Effortlessly transform query parameters into JPA predicates.
- 🎯 Comprehensive Operators: Supports a wide variety of filtering operators for flexibility.
- 🔒 Type-Safe Validation: Ensures data integrity with robust parameter validation.
- 🎨 Clean API Design: Provides an intuitive and developer-friendly API.
- 🔌 Spring Data Integration: Seamlessly works with Spring Data JPA and Hibernate.
- 📦 Nested Property Filtering: Enables filtering across related entities with ease.
- 🛠 Extensibility: Highly customizable to adapt to project-specific requirements.
- Java: Version 17 or higher
- Spring Boot: Version 3.1.0 or higher
- Jakarta Persistence API: Version 3.1.0 or higher
To integrate Query Filter Builder into your project, add the following Maven dependency:
<dependency>
<groupId>io.github.0xorigin</groupId>
<artifactId>query-filter-builder</artifactId>
<version>1.0.0</version>
</dependency>
Follow these simple steps to start using Query Filter Builder:
- Define a Specification: Create a
Specification
for your entity. - Inject QueryFilterBuilder: Use the
QueryFilterBuilder
to simplify the construction of JPA predicates. - Build a Filter Context:
- Use
addFilter(String fieldName, Operator... operators)
to define entity filters. - Use
addFilter(String fieldName, Class<? extends Comparable<?>> dataType, CustomFilterFunction<T> filterFunction)
for custom filters.
- Use
- Generate Predicates: Invoke
buildFilterPredicate
to create dynamic JPA predicates. - Return the Predicate: Integrate the predicate into your
toPredicate
method.
@Service
public class UserSpecification implements Specification<User> {
private final QueryFilterBuilder<User> queryFilterBuilder;
public UserSpecification(QueryFilterBuilder<User> queryFilterBuilder) {
this.queryFilterBuilder = queryFilterBuilder;
}
@Override
public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
return cb.and(getQueryFilterPredicate(root, query, cb));
}
private Predicate getQueryFilterPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
FilterContext<User> filterContext = new FilterContext<>();
filterContext.addFilter("createdBy", Operator.EQ)
.addFilter("isActive", Operator.IS_NULL, Operator.IS_NOT_NULL)
.addFilter("lastLogin", Operator.EQ, Operator.GTE)
.addFilter("createdBy__lastLogin", Operator.EQ)
.addFilter("search", String.class, this::search);
return queryFilterBuilder.buildFilterPredicate(root, query, cb, filterContext);
}
private Predicate search(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb, List<?> values, ErrorWrapper errorWrapper) {
return cb.or(cb.equal(root.get("firstName"), values.get(0)), cb.equal(root.get("lastName"), values.get(0)));
}
}
Query Filter Builder uses a consistent, delimiter-based format for query parameters:
field__path__to__property__operator=value
- Default delimiter:
__
(double underscores) - Customizable: Override the delimiter using the
query-filter-builder.defaults.field-delimiter
property in your application's configuration.
Examples:
# Basic filtering
/api/users?name=john&age__gte=18
# Nested property filtering
/api/users?department__name__endsWith=Engineering&[email protected]
# Complex filtering
/api/users?createdBy__lastLogin__between=2024-01-01,2024-12-31&status__in=ACTIVE,PENDING
Operator | Description |
---|---|
eq |
Equal to |
neq |
Not equal to |
gt |
Greater than |
gte |
Greater than or equal to |
lt |
Less than |
lte |
Less than or equal to |
in |
In a list of values |
notIn |
Not in a list of values |
isNull |
Is null |
isNotNull |
Is not null |
contains |
Contains string |
icontains |
Case-insensitive contains |
startsWith |
Starts with |
istartsWith |
Case-insensitive starts with |
endsWith |
Ends with |
iendsWith |
Case-insensitive ends with |
between |
Between two values |
notBetween |
Not between two values |
Byte
,Short
,Integer
,Long
,Float
,Double
,Boolean
Character
,String
UUID
Instant
,OffsetDateTime
,ZonedDateTime
,OffsetTime
,LocalDateTime
,LocalDate
,LocalTime
,YearMonth
,Year
Comprehensive error handling is provided for invalid query parameters and misconfigurations. Use exception handlers to customize responses.
- Fork the repository
- Create a feature/bug branch
- Commit your changes
- Push to the branch
- Create a Pull Request
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.