Spring Search provides advanced search capabilities to a JPA entity
Explore the docs »
View Demo
·
Report Bug
·
Request Feature
Spring Search provides a simple query language to perform advanced searches for your JPA entities.
Let's say you manage cars, and you want to allow API consumers to search for:
You could either create custom repository methods for both these operations, which works well if you know in advance which fields users might want to perform searches on. You could also use spring-search that allows searching on all fields, combining logical operators and much more.
Please note that providing such a feature on your API does not come without risks such as performance issues and less clear capabilities for your API. This article summarizes these risks well.
Requirements : JDK 8 or more.
To get a local copy up and running follow these simple steps.
Add the repo to your project inside your pom.xml
file
<dependency>
<groupId>com.sipios</groupId>
<artifactId>spring-search</artifactId>
<version>0.2.6</version>
</dependency>
Add the repo to your project by adding implementation 'com.sipios:spring-search:0.2.0'
in your build.gradle
file.
Your repository should be annotated as a RepositoryRestResource
and should extend JpaSpecificationExecutor
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.JpaSpecificationExecutor
import org.springframework.data.rest.core.annotation.RepositoryRestResource
@RepositoryRestResource
interface YourRepository : JpaRepository<YourModel, Int>, JpaSpecificationExecutor<YourModel>
Import the library in your controller
import com.sipios.springsearch.anotation.SearchSpec
Use it in your controller
@GetMapping("searchUrl")
fun yourFunctionNameHere(@SearchSpec specs: Specification<YourModel>): ResponseEntity<List<YourResponse>> {
return ResponseEntity(yourRepository.findAll(Specification.where(specs)), HttpStatus.OK)
}
Operator | Description | Example |
---|---|---|
: |
Equal | color:Red |
! |
Not equal | color!Red |
> |
Greater than | creationyear>2017 |
>: |
Greater than eq | creationyear>2017 |
< |
Less than | price<100000 |
<: |
Less than eq | price<100000 |
* |
Starts with | brand:*Martin |
* |
Ends with | brand:Aston* |
* |
Contains | brand:*Martin* |
OR |
Logical OR | color:Red OR color:Blue |
AND |
Logical AND | brand:Aston* AND price<300000 |
IN |
Value is in list | color IN ['Red', 'Blue'] |
NOT IN |
Value is not in list | color NOT IN ['Red', 'Blue'] |
IS EMPTY |
Collection field is empty | cars IS EMPTY |
IS NOT EMPTY |
Collection field is not empty | cars IS NOT EMPTY |
IS NULL |
Field is null | brand IS NULL |
IS NOT NULL |
Field is not null | brand IS NOT NULL |
() |
Parenthesis | brand:Nissan OR (brand:Chevrolet AND color:Blue) |
BETWEEN |
Value is between two values | creationyear BETWEEN 2017 AND 2019 |
NOT BETWEEN |
Value is not between two values | creationyear NOT BETWEEN 2017 AND 2019 |
/cars?search=( brand:Nissan OR brand:Chevrolet ) AND color:Blue
/cars?search=model:'Spacetourer Business Lounge'
/cars?search=model:中华V7
/cars?search=options.transmission:Auto
/cars?search=creationyear:2018 AND price<300000 AND (color:Yellow OR color:Blue) AND options.transmission:Auto
/cars?search=creationyear BETWEEN 2017 AND 2019
@GetMapping
public List<User> getUsers(@SearchSpec(blackListedFields = {"password"}) Specification<User> specs) {
return userRepository.findAll(Specification.where(specs));
}
If you get the following error ⬇️
No primary or default constructor found for interface org.springframework.data.jpa.domain.Specification
You are free to opt for either of the two following solutions :
Add a @Configuration
class to add our argument resolver to your project
// Kotlin
@Configuration
class SpringSearchResolverConf : WebMvcConfigurer {
override fun addArgumentResolvers(argumentResolvers: MutableList<HandlerMethodArgumentResolver>) {
argumentResolvers.add(SearchSpecificationResolver())
}
}
// Java
@Configuration
public class SpringSearchResolverConf implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new SearchSpecificationResolver());
}
}
Add a @ComponentScan
annotation to your project configuration class
@ComponentScan(basePackages = {"com.your-application", "com.sipios.springsearch"})
See the open issues for a list of proposed features (and known issues).
Please note that boolean parameter types are yet to be supported.
Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are greatly appreciated.
git checkout -b feature/AmazingFeature
)git commit -m 'Add some AmazingFeature'
)git push origin feature/AmazingFeature
)Distributed under the MIT License. See LICENSE
for more information.
@sipios_fintech - contact@sipios.com
Project Link: https://github.com/sipios/spring-search