Home > Software design >  How to combine 2 or more endpoints into one spring-boot?
How to combine 2 or more endpoints into one spring-boot?

Time:03-09

I need your help. For example, I have 2 controllers with which I create 2 urls to work with products:

https://localhost:8080/laptops - for laptops, https://localhost:8080/smartphones - for smartphones

Each of them accepts all CRUD operations. I want that when I type a url that looks like this https://localhost:8080/data in response I received data from two previous urls. Please tell, how is it possible to do it? Thank you very much

CodePudding user response:

  • There is too many ways to do this, a simple way is to add a something like a flag to the request (request body or parameter in case it is a get request).
  • In the code bellow i used a key value map (Map<String, String) in order to make the service generic.
  • The 'clazz' is used to check which service is wanted to be run.
  • It's possible to make a default behaviour in case the 'clazz' attribute is null or malformed.
  • Finally, to parse the fetch reuslt easily you can add the class name in each element.
@RestController
@RequiredArgsConstructor
public class DataController {
    public static final String CLAZZ = "clazz";
    private final ObjectMapper objectMapper;

    @PostMapping("/add")
    public ResponseEntity<Map<String, String>> add(@RequestBody final Map<String, String> data) {
        Map<String, String> result = new HashMap<>();

        if(data.containsKey(CLAZZ)){
            String clazz = data.get(CLAZZ);

            if(clazz.equals(Laptop.class.getCanonicalName())){
                Laptop laptop = objectMapper.convertValue(data, Laptop.class);
                //call your laptop service here to add a new laptop and return the new object into laptop instance
                result = objectMapper.convertValue(laptop, Map.class);
            }else if(clazz.equals(Smartphone.class.getCanonicalName())) {
                Smartphone smartphone = objectMapper.convertValue(data, Smartphone.class);
                //call your smartphone service here to add a new smartphone and return the new object into smartphone instance
                result = objectMapper.convertValue(smartphone, Map.class);
            }
        }
        return ResponseEntity.ok(result);
    }

    @GetMapping("/fetch")
    public ResponseEntity<List<Map<String, String>>> fetch(){
        List<Map<String, String>> result = new ArrayList<>();
        
        List<Laptop> laptops = Collections.emptyList(); // here you need to call your laptop service
        result.addAll(laptops.stream().map(laptop -> (Map<String, String>) objectMapper.convertValue(laptop, Map.class)).collect(Collectors.toList()));
        
        List<Smartphone> smartphones = Collections.emptyList(); // here you need to call your smartphone service
        result.addAll(smartphones.stream().map(smartphone -> (Map<String, String>) objectMapper.convertValue(smartphone, Map.class)).collect(Collectors.toList()));
        return ResponseEntity.ok(result);
    }
}

CodePudding user response:

It is always better to have single url with query parameter has filter.

Example: http://localhost:8080/electronics?type=type

Then you can read from the query param and filter accordingly.

  • Related