For the sake of simplicity lets assume I have a Document
object with seven fields (but imagine that it can have many more). This object looks something like this:
@Getter
@Setter
public class Document {
private String fileName;
private String fileType;
private String createdBy;
private Date createdAt;
private Date lastModifiedAt;
private List<String> modifiers;
private Long timesModified;
}
I want to create an endpoint which can receive any number of @RequestParam
and returns a List<Document>
of all the documents which match the given query. For example: return all documents with fileType == doc
, which were created between createdAt == 01/01/2021 && createdAt 31/01/2021
, modified timesModified == 5
times and modifiers.contains("Alex")
. The reason for this is that I want to allow the user to query for documents depending on combination of fields the user wants. Originally to handle this we created the endpoint like so:
@GetMapping(value = {RestApi.LIST})
public ResponseEntity<List<Document>> getDocuments (@RequestParam Map<String, Object> optionalFilters) {
List<Document> documents = documentService.getListOfDocuments(optionalFilters);
if (documents != null) {
return new ResponseEntity<>(documents, HttpStatus.OK);
}
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
The problem with this is that because we use optionalFilters
as Map<String, Object>
this requires us to perform a lot of casting in our code and overall makes our code very tedious and cumbersome because we have to iterate through the whole map and create a custom query depending the fields that were passed. In order to try and improve this I created an OptionalFilters
object:
@Getter
@Setter
@NoArgsConstructor
public class OptionalFilters {
private String fileName;
private String fileType;
private String createdBy;
private Date createdAt;
private Date lastModifiedAt;
private List<String> modifiers;
private Long timesModified;
}
And modified the endpoint to this:
@GetMapping(value = {RestApi.LIST})
public ResponseEntity<List<Document>> getDocuments (@Valid OptionalFilters optionalFilters) {
List<Document> documents = documentService.getListOfDocuments(optionalFilters);
if (documents != null) {
return new ResponseEntity<>(documents, HttpStatus.OK);
}
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
However, although that this simplifies the way we receive the parameters and extract the values from them, we still need to iterate through all the parameters and create a custom query. Is there some way to elevate and take advantage of Spring-Data
(or any other solution) so that I don't have to create a custom query depending on each query param that is passed through? I am using Solr
as the repository if this may be any help.