Search code examples
spring-bootswaggerspringfox

Automatically document @PathVariable annotated parameters within @ModelAttribute annotated methods


In our REST-API we need to be multi-tenant capable. For achiving this all rest controllers subclass a common REST controller which defines a request mapping prefix and exposes a model attribute as follows

@RequestMapping(path = "/{tenantKey}/api")
public class ApiController {

   @ModelAttribute
   public Tenant getTenant(@PathVariable("tenantKey") String tenantKey) {
     return repository.findByTenantKey(tenantKey);
   }

}

Derived controllers make use of the model attributes in their request mapping methods:

@RestController
public class FooController extends ApiController {

  @RequestMapping(value = "/foo", method = GET)
  public List<Foo> getFoo(@ApiIgnore @ModelAttribute Tenant tenant) {
    return service.getFoos(tenant);
  }

}

This endpoint gets well documented in the swagger-ui. I get an endpoint documented with a GET mapping for path /{tenantKey}/api/foo.

My issue is, that the {tenantKey} path variable is not documented in swagger-ui as parameter. The parameters section in swagger is not rendered at all. If I add a String parameter to controller method, annotating it with @PathVariable("tenantKey) everything is fine, but I don't want a tenantKey parameter in my controller method, since the resolved tenant is already available as model attribute.

So my question is: Is there a way do get the @PathVariable from the @ModelAttriute annotated method in ApiController documented within swagger-ui in this setup?

Project-Setup is

  • Spring-Boot (1.4.2)
  • springfox-swagger2 (2.6.1)
  • springfox-swagger-ui (2.6.1)

Solution

  • This is certainly possible. Model attributes on methods are not supported currently. Instead, you could take the following approach.

    1. Mark the getTenant method with an @ApiIgnore (not sure if it gets treated as a request mapping.)
    2. In your docket you can add tenantKey global path variable (to all end points). Since this is a multi-tenant app it's assuming this applies to all endpoints.