Reputation: 93
I am trying to create a GET endpoint in spring with multiple Optional Request parameters to query data from mongo (think and query) and return it.
What I have so far- MyController.java
@GetMapping
public ResponseEntity<Iterable<Item>> searchItem(@RequestParam Map<String, Optional<String>> requestParams){
List<Item> items = itemService.findItem(requestParams);
return (new ResponseEntity<>(Item, HttpStatus.Ok));
}
@GetMapping
public ResponseEntity<Iterable<Item>> getAllItems(){
Iterable<Item> items= itemService.listItems();
return (new ResponseEntity<>(items, HttpStatus.OK));
}
Heres my service layer-
@Override
public List<Item> findItem(Map<String,Optional<String>> params) {
QItem qItem = QItem.item;
BooleanBuilder builder = new BooleanBuilder();
params.forEach( (String key, Optional<String> value) -> {
if(value.isPresent()) {
builder.and(qUser.key.eq(value.get()));
}
});
List<Item> items = itemRepository.findAll(builder);
return resultItems;
}
@Override
public Iterable<Item> listItems() {
List<Item> items = userRepository.findAll();
return items;
}
If it isn't apparent already, I am struggling to build the predicate using booleanBuilder and pass it to the repository layer. The key in the map will contain the name of the QItems required field name.
Also how do I resolve the 2 GET Mappings for get all users and get by parameter? I can make a GET request -> /item to retrieve all items or I can make a GET request with params to query by parameters -> /item?param1=value1¶m2=value2
Upvotes: 1
Views: 1347
Reputation: 807
For your first question you can use Expression.stringPath() method to get full path of parameter from root object as following,
@Override
public List<Item> findItem(Map<String,Optional<String>> params) {
QItem qItem = QItem.item;
BooleanBuilder builder = new BooleanBuilder();
params.forEach( (String key, Optional<String> value) -> {
if(value.isPresent()) {
StringPath column = Expressions.stringPath(qItem, key);
builder.and(column.eq(value));
}
});
List<Item> items = itemRepository.findAll(builder);
return resultItems;
}
For your second clarification, it's based on your choice but you can do both in a single GetMapping by adding some condition for checking whether your params map empty or not,
If empty -> call itemRepository.findAll(),
else -> call itemRepository.findAll(builder)
Upvotes: 1