LunaticJape
LunaticJape

Reputation: 1584

how to use spring boot to handle different search?

What's the best practice to create search function in spring boot with spring data jpa?

@GetMapping("/search")
public List<Hotel> getAllByCriteria(@RequestParam MultiValueMap<String, String> criteria) {
    if (criteria.containsKey("cityPublicId")) {
        String cityPublicId = criteria.getFirst("cityPublicId");
        if (criteria.containsKey("amenity")) { 
            List<String> amenities = criteria.get("amenity");
            return svc.findAllByCityAndAmenities(cityPublicId, amenities);
           }
        return svc.findAllByCity(cityPublicId);
    }
    //currently only support one amenity filtration
    else if (criteria.containsKey("amenity")) {
        return svc.findAllByAmenities(criteria.get("amenity"));
    }
    return null;
}

Currently I have to identify all possible combination of criteria to use corresponding method, Is there a universal way to handle all condition? Or at least not hardcoding all possible combination.

PS: If I want to filter result by multiple amenities, may I use findByAmenitiesContains(set)? Where a Hotel entity has a set of amenity. Do I have to create custom query using @query?

Thanks.

Upvotes: 0

Views: 2587

Answers (2)

Jens Schauder
Jens Schauder

Reputation: 81988

You basically have the following options:

  • create the query programmatically from the input data using a custom method. This gives you maximum flexibility but also requires the most work.

  • Use a specification. Almost the same flexibility and almost as much work.

  • Use query by example. Very little work, limited flexibility.

Regarding the PS: The capabilities of query derivation are well documented.

Upvotes: 1

Alex
Alex

Reputation: 7936

AFAIR you can use different request payload entities to handle the same endpoint

@GetMapping(path = "/search", params = { "cityId" })
public List<Hotel> getAllByCriteria(ByCityPublicId byCity) {
    return svc.findAllByCity(byCity.getCityPublicId())
}

@GetMapping(path = "/search", params = { "cityId", "amenity" })
public List<Hotel> getAllByCriteria(ByCityPublicIdAndAmenity byCityAndAmenitities) {
    return svc.findAllByCityAndAmenities(byCityAndAmenitities.getCityPublicId(), byCityAndAmenitities.getAmenitities())
}

@GetMapping(path = "/search", params = { "amenity" })
public List<Hotel> getAllByCriteria(ByAmenity byAmenity) {
    return svc.findAllByAmenities(byAmenity.getAmenity());
}

Upvotes: 1

Related Questions