I am implementing a product search feature where user can search for products based on name, brand, and price. I have written different endpoints for searching for different combination and I hate the code and I cannot add additional filters easily and have to create all the combination for any additional filter I have to add.
My Product Repository -
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import com.vaibhavshrivastava.productbrowser.model.Product;
public interface ProductRepository extends JpaRepository<Product, Integer> {
//
public List<Product> findByName(String name);
public List<Product> findByNameAndProductCode(String name, int productCode);
public List<Product> findByNameAndBrand(String name, String brand);
public List<Product> findByNameAndBrandAndProductCode(String name, String brand, int productCode);
public List<Product> findByBrand(String brand);
public List<Product> findByProductCode(int productCode);
public List<Product> findByBrandAndProductCode(String brand, int productCode);
// public int getPrice(int productCode);
public Optional<Product> findByProductCode(Integer productCode);
}
My Product Controller -
@RestController
@CrossOrigin
@RequestMapping("/products")
public class ProductController {
@Autowired
ProductRepository productRepository;
@Autowired
ProductService productService;
@GetMapping("/nameandbrand")
public ResponseEntity<List<Product>> getProductsByNameAndBrand(@RequestParam String name,
@RequestParam String brand) {
return new ResponseEntity<>(productRepository.findByNameAndBrand(name, brand), HttpStatus.OK);
}
@GetMapping("/nameandproductcode")
public ResponseEntity<List<Product>> getProductsByNameAndProductCode(@RequestParam String name,
@RequestParam int productCode) {
return new ResponseEntity<>(productRepository.findByNameAndProductCode(name, productCode), HttpStatus.OK);
}
@GetMapping("/name")
public ResponseEntity<List<Product>> getProductsByName(@RequestParam String name) {
return new ResponseEntity<>(productRepository.findByName(name), HttpStatus.OK);
}
@GetMapping("/nameandbrandandproductcode")
public ResponseEntity<List<Product>> getProductsByNameOrBrandOrProductCode(@RequestParam String name, @RequestParam String brand, @RequestParam int productCode){
return new ResponseEntity<>(productRepository.findByNameAndBrandAndProductCode(name, brand, productCode), HttpStatus.OK);
}
@GetMapping("/brand")
public ResponseEntity<List<Product>> getProductsByBrand(@RequestParam String brand){
return new ResponseEntity<>(productRepository.findByBrand(brand), HttpStatus.OK);
}
@GetMapping(name="/productcode")
public ResponseEntity<Optional<Product>> getProductsByProductCode(@RequestParam Integer productCode){
return new ResponseEntity<>(productRepository.findByProductCode(productCode), HttpStatus.OK);
}
@GetMapping("/brandandproductcode")
public ResponseEntity<List<Product>> getProductsByBrandAndProductCode(@RequestParam String brand, @RequestParam int productCode){
return new ResponseEntity<>(productRepository.findByBrandAndProductCode(brand, productCode), HttpStatus.OK);
}
@GetMapping("/{pid}/details")
public ResponseEntity<Product> getProductDetails(@PathVariable("pid") Integer productCode){
System.out.println("PPPPPPPPPPRDDDDDDDCTTTT CODEEEEE" + productCode);
Product selectedProduct = productRepository.findByProductCode(productCode).orElseThrow();
return new ResponseEntity<>(selectedProduct, HttpStatus.OK);
}
@GetMapping("/")
public List<Product> getProducts(){
return productService.getProducts();
}
}
I have not yet added the Price filter and I have to add it so I have to make all the combinations to search with price filter too. What is the best way to implement something like this?
I am sending parameters using angular on the frontend.
How to transform this bad code into something in which I can add additional filters easily.
My Product Entity have these fields -
@Entity
public class Product {
@Id
private int productCode;
private String name;
private String brand;
private String description;
private int price;
private String img;
(Not included hash and getters and setters etc)