Search code examples
javaspringspring-bootspring-restcontrollerambiguous

Spring boot endpoint parameter signature, is throwing ambiguous endpoint exception when both parameters are given


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


Solution

  • 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