Customizing Request Header description in Swagger UI using Springfox-Swagger2
Asked Answered
N

4

12

I am using Springfox Swagger2 version 2.4.0, Springfox Swagger UI version 2.4.0 and Swagger Annotations version 1.5.0 in my Spring Boot application.

The problem is, I am able to generate swagger UI for my controller's API and I am able to test it, but I am not able to specify request header description for my request header. I'm using @RequestHeader annotation.

Code snippet in my controller API:

@RequestHeader(name = "Api-Key")  String apiKey

Swagger UI for the request header:

enter image description here

The highlighted rectangular area in the image represents the description of the request header.

For now, it just picks up the data mentioned in the name attribute and shows it, but I wanna give it a different description, i.e. "Value of license key"

How can I achieve this in Swagger UI as @RequestHeader annotation only have value, defaultValue, name and required attributes? Any help would be really appreciated.

Update: Looking for a solution out of the box without any custom annotation of my own.

Noel answered 20/2, 2017 at 15:39 Comment(2)
I am confused with RequestHeader exactly as described. ApiParam(name, value, ..) makes sense to me, and #value() is explicitely described for "description" (io.swagger.annotations v2.9.2 in my case). However the interface declaration of @RequestHeader in (spring-web.bind.annotations 5.0.12 in my case) declares #value() with an AliasFor("name") and #name() with an AliasFor("value") where setting of both at the same time results in a render error. Is this a bug or should this be reversed RequestHeader::value() should behave analog ApiParam::value() as a description field?Noisy
@Parameter(description = "description") seems to work as wellBounce
M
14

Maybe my answer will help somebody.

As mentioned Dilip Krishnan in his answer you could use io.swagger.annotations.ApiParam or io.swagger.annotations.ApiImplicitParam Swagger annotations for fine-tuned custom documentation.

@ApiParam could be used for registered method parameters.

@ApiImplicitParam could be used if API parameter wasn't registered explicitly.

@RestController
@RequestMapping(value = "/v1/test", produces = "application/json")
@Api(value = "/v1/test")
public class TestController {
    
    @ApiOperation(value = "Do Something method", tags = "Test method")
    @RequestMapping(value = "/doSomeThing", method = RequestMethod.GET)
    public Foo doSomeThing(
            @ApiParam(value = "Param1 Description", required = true)
            @RequestParam String param) {
        throw new UnsupportedOperationException("do Some Things");
    }
    
    @ApiOperation(value = "Do Something Another method", tags = "Test method")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "anotherParam1", value = "Another Param1 Description", paramType = "header"),
            @ApiImplicitParam(name = "anotherParam1", value = "Another Param1 Description", paramType = "header")
    })
    @RequestMapping(value = "/doSomeThingAnother", method = RequestMethod.GET)
    public Foo doSomeThingAnother(Bar bar) {
        throw new UnsupportedOperationException("do Some Thing Another");
    }
}    

And in the end you could see following picture

Swagger UI for custom method description

Menzies answered 26/9, 2017 at 9:51 Comment(5)
I was looking for something to do on top of request header param. Unfortunately not api implicit paramNoel
Description was updated for regular request parameter.Menzies
@ApiParam(value="header description") can be used along with @RequestHeader to provide header description. @DmytroBoichenko update the answer with this.Entoderm
@ChackoMathew I'm sorry mate, but currently I don't have this code and can't check your solution.Menzies
@DmytroBoichenko I tried this way, but I can't see this value is sent as a header when I investigate the network tab of browser tools.Manzano
S
4

TL;DR is that you would have to build your own plugin to do it.

Basically the only out-of-the-box annotations to augment the description in this case are @ApiParam and to be more accurate @ApiImplicitParam. Unfortunately neither of those annotations support descriptions.

So my suggestion would be to:

  1. Create your own annotation that would look like this

    @RequestHeader(name = "Api-Key") @Description("Value of license key") String apiKey

NOTE: There is already an annotation in spring that is suitable for this.

  1. Create your own ParameterBuilderPlugin
  2. Implement the plugin as shown below
public class Test implements ParameterBuilderPlugin {
  @Override
  public void apply(ParameterContext parameterContext) {
    ResolvedMethodParameter methodParameter =parameterContext.resolvedMethodParameter();
    Optional<Description> requestParam = methodParameter.findAnnotation(Description.class);
    if (requestParam.isPresent()) {
      parameterContext.parameterBuilder()
        .description(requestParam.get().value());
    }
  }

  @Override
  public boolean supports(DocumentationType documentationType) {
    return false;
  }
}
  1. Pick a value of the order that is is applied after swagger annotations have been processed.

Also please upgrade your springfox library to the latest version.

Seton answered 21/2, 2017 at 5:20 Comment(3)
Thank you for your quick response. Dont have much exposure on things you say, so will try out and get back to you. Thanks againNoel
Finally got time to start on this. But i m stuck at the start as i m fairly new to this. As you mentioned, i tried placing description annotation to my request header param and got an error like - "annotation type not applicable to this kind of declaration" Can you guide me in this? Also should i place the test class in your post in my spring application code? Lastly, i m not very clear about what you meant in step-4 Please adviceNoel
When u create your annotation make sure it applies to parameters as well. Using the one that comes with spring may not work. Step 4 is simply saying make sure your plugin runs after swagger plugins. These plugins use springs Ordering for beans.Seton
K
0

We had the same issue, and resolved the problem in the following way:

.. @RequestHeader(value = "..") @ApiParam(value = "Description") String param ..

The idea is to add "description" field into generated swagger. It could look hacky, but it's a quick simple solution which can be useful in your personal case.

Kendra answered 2/4, 2019 at 15:1 Comment(2)
Guess that will add a new param and not update the header descriptionNoel
Yep, right you are. If the goal is only swagger, it could help. But in general case it's better to use solutions above.Kendra
P
0

Quick, easy valid solution is to use an enum, for example:

@RequestHeader(value = "someval") ALLOWED_VALUES input

private enum ALLOWED_VALUES {A, B, C};

The following will show in swagger: Available values : A, B, C

Peristyle answered 16/7, 2020 at 18:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.