Due to the way it was engineered in the past, there was one endpoint created for a specific parameter called foo
in this case.
However the requirement meant that the endpoint could be used either with foo
or a new parameter called bobby
.
After trying to consolidate into one endpoint, the refactor work was too much.
So I opted for overloading the endpoint and using the spring boot trick to have the signature dictated by the request params.
Like so:
@GetMapping(params = {"foo"})
public CollectionResource<FooResource> get(@RequestParam("foo") String foo, ...) {} ...
@GetMapping(params = {"bobby"})
public CollectionResource<FooResource> get(@RequestParam("bobby") {} ...
This works well when interacting with the endpoints like so:
localhost:8080/testEndpoint?foo=bar
localhost:8080/testEndpoint?bobby=tables
However I discovered an edge case when trying the following:
localhost:8080/testEndpoint?bobby=tables&foo=bar
Which throws the following runtime exception
java.lang.IllegalStateException: Ambiguous handler methods mapped for HTTP path 'http://localhost:8080/testEndpoint/':
This endpoint is not hit by users but programmatically, so its very low chance this case would happen. However is there a way to setup the controller so it can handle this and just throw a BadRequest etc. instead of blowing up?
Spring Boot Version : 1.5.16.RELEASE
Why not choose a primary endpoint?
For the first, just add the additional parameter to it
public CollectionResource<FooResource> get(@RequestParam("foo") String foo, ...
,@RequestParam("bobby")) {
By that first endpoint will be chosen in this corner case