Introduction
In this article/tutorial we are going to learn how to use @Pathvariable with optional value in endpoint URL. For example let us consider an example where one handler method has to perform two different endpoints requests. One regular way is creating two different endpoints for processing different requests. Consider an example where Cars data need to be inserted into database table with @RequestBody ( this is useful to get JSON data as an input to REST endpoint ). And consider there is one-to-many mapping between person and cars data tables. Then we need to pass person_id along with car details as a JSON input to the endpoint or To pass person id we can use @Pathvariable.
/** * This handling method for adding new car by padding pid(personID) as a PathVariable is mandatory * @param cars * @param pid * @return */ @PostMapping("/addNewCar/{ownerid}") public Cars addNewCars(@RequestBody Cars cars, @PathVariable("ownerid") Long pid) { return carService.addNewCars(personRepository.findById(pid).map((Person person1) -> { cars.setPerson_car(person1); return cars; }).get()); } /** * This is the method for adding new car without passing pid( person_id ) as Pathvariable * @param cars * @return */ @PostMapping("/addNewCar") public Cars addNewCars(@RequestBody Cars cars) { return carService.addNewCars(personRepository.findById(cars.getPid()).map((Person person1) -> { cars.setPerson_car(person1); return cars; }).get()); }
Following figure shows endpoint with pathavariable
with pathvariable |
Following figure shows endpoint without pathvariable, but you can see there is additional JSON element pid in input
without pathvariable |
Following figure shows comparison between difference in JSON input
with pathvariable vs without pathvarialbe |
Using required=false parameter
We can use required=false paramter along with @PathVariable by passing multiple endpoint to single mapping annotation. For example the above code will turn into the following
@PostMapping(value = { "/add", "/add/{ownerid}" }) public Cars addNewCar(@PathVariable(value = "ownerid", required = false) Long pid, @RequestBody Cars cars) { pid = ((pid != null) ? pid : (pid = cars.getPid())); return carService.addNewCars(personRepository.findById(pid).map(p -> { cars.setPerson_car(p); return cars; }).get()); }
Observe that two methods turns into single method in the above example.
Following is the screen output for adding new car by passing person id as endpoint pathvariable where endpoint is http://localhost:8080/cars/add/4
pathvariable included for person id |
Following is the screen for adding new car without pathvariable in endpoint url where endpoint is http://localhost:8080/cars/add, but person id passed as a JSON input element
No pathvariable in endpoint, but passed personID as JSON input |
Using Optional<T> as a pathvariable type
We can use Optional<T> as a pathvariable type to handle different endpoints requests based on existence of pathvariable , following is the code with Otpional<T> as a pathvariable.
/** * Using Optional<T> as a pathvariable * @param id * @param cars * @return */ @PostMapping(value = { "/addC", "/addC/{pid}" }) public Cars addNewCarsOptional(@PathVariable(value = "pid") Optional<Long> id, @RequestBody Cars cars) { Long pid = (Long) (id.isPresent() ? id.get() : cars.getPid()); return carService.addNewCars(personRepository.findById(pid).map(p -> { cars.setPerson_car(p); return cars; }).get()); }
Following is the screen output for pathvariable with Optional<T>
Optional As a pathvariable |
without pathvariable |
Using Map as a pathvariable type
Using Map as a path variable type is available from Spring 3.2 version. First one is representing Pathvariable value attribute.
/** * Using Map<String, String> as a pathvariable * @param id * @param cars * @return */ @PostMapping(value = { "/addCMap", "/addCMap/{pid}" }) public Cars addNewCarsMap(@PathVariable Map<String, String> id, @RequestBody Cars cars) { Long pid = (id.get("pid")!=null ? Long.parseLong(id.get("pid")) : cars.getPid()); return carService.addNewCars(personRepository.findById(pid).map(p -> { cars.setPerson_car(p); return cars; }).get()); }
Map with Pathvariable |
Map without Pathavraible |
Post a Comment
Post a Comment