Search code examples
spring-bootrestspring-mvcswaggerswagger-ui

Can we have two @PathVariable. One as the actual Path Variable and other for swagger to document it as Deprecated?


I am trying to change the REST call's @PathVariable. The existing Path Variable is formed by combination of three parameters. The change is to handle Path Variable formed by combination of two parameters. I need this change to be documented in swagger with the earlier shown as Deprecated. I have tried to use both Path Variable with one as @Deprecated like below

@Parameter(description = "x_y_z - x is first ID, y is second ID, z is third ID", required=false )
            @Deprecated @PathVariable String x_y_z,
@Parameter(description = "x_y - x is first ID, y is second ID", required=true )
            @PathVariable String x_y)

The have changed request mapping value from /aaa/bbb/{x_y_z} to below

@RequestMapping(value = "/aaa/bbb/{x_y}", method = RequestMethod.GET, produces = "application/json"

With above changes the request fails with 500 error, may be since it is expecting two Path Variables. But the swagger documentation is as expected.

I tried to remove @PathVariable for x_y_z. The request is processed as expected and the swagger now shows x_y_z as deprecated but shows the parameter as (query) instead of (path)

Any suggestions please


Solution

  • Assuming an @RestController and that Swagger understands @Deprecated for a method:

    @Deprecated
    @GetMapping("/aaa/bbb/{x:\\d+}_{y:\\d+}_{z:\\d+}")
    public ResponseEntity<MessageResponse> getStuff(@PathVariable String x,
                                                    @PathVariable String y,
                                                    @PathVariable(name = "z", required = false) String z) {
    
        return getNewStuff(x, y); //send to the other method and ignore z
    }
    
    @GetMapping("/aaa/bbb/{x:\\d+}_{y:\\d+}")
    public ResponseEntity<MessageResponse> getNewStuff(@PathVariable String x,
                                                       @PathVariable String y) {
        // do stuff for x and y by default
        return ResponseEntity.ok(new MessageResponse("this method is supported for " + x + " and " + y));
    }
    

    The RegEx should look for digits as the path variables, interspersed with underscores.

    NB: leaving this part of the answer if Swagger works with it instead with the understanding that it could be deprecated:

    @PathVariable @Parameter(description = "x_y_z - x is first ID, y is second ID, z is third ID", deprecated = true) String z
    

    Deprecating the original method and introducing a new method with the correct parameters but different RequestMapping could also be a valid workaround.

    The other part to note is that it is more common to use slashes as the delimiter rather than underscores in Spring (e.g., /aaa/bbb/x/y). You also may wish to include a validator that fits your requirements.