Add a header parameter in Swagger UI documentation with Springfox
Asked Answered
R

5

27

I want to add a header parameter field in the auto-generated swagger ui documentation of my rest service. I use Spring and Springfox.

public ResponseEntity<User> saveNewUser(
        @ApiParam(value = "the user to create", required = true) @RequestBody User user) throws RestServiceException {

    userService.save(user);
    return new ResponseEntity<User>(user, HttpStatus.OK);
}

As you see I have already a body type parameter. I just want to add a header type one.

Reynolds answered 25/11, 2016 at 9:22 Comment(0)
R
20

I just added @RequestHeader(value="myHeader") String headerStr :

public ResponseEntity<User> saveNewUser(
        @RequestHeader(value="myHeader") String headerStr,
        @ApiParam(value = "the user to create", required = true) @RequestBody User user) throws RestServiceException {

    userService.save(user);
    return new ResponseEntity<User>(user, HttpStatus.OK);
}

(import org.springframework.web.bind.annotation.RequestHeader;)

You can also add a global header on every service in your documentation with the solution described here : Spring + Springfox + Header Parameters

Reynolds answered 25/11, 2016 at 9:22 Comment(0)
T
49

I prefer to use @ApiImplicitParam after my @RequestMapping rather than as function parameters because generally you might process your headers in a filter (eg authentication) and you are not needing the values in that method.

Besides if you need them in the method Swagger auto provides the field for a @HeaderParam

This style also Improves readability and flexibility when some calls need headers and other don't.

Example

@PostMapping
@ApiImplicitParam(name = "Authorization", value = "Access Token", required = true, allowEmptyValue = false, paramType = "header", dataTypeClass = String::class, example = "Bearer access_token")
fun addJob(jobRequest: Job): ResponseEntity<*>{}

If all or most for your endpoints need header that I'll rather configure it as seen here

If you have to declare several header params, you need to use the @ApiImplicitParams annotation:

@PostMapping
@ApiImplicitParams({
  @ApiImplicitParam(name = "Authorization", value = "Access Token", required = true, allowEmptyValue = false, paramType = "header", dataTypeClass = String.class, example = "Bearer access_token"),
  @ApiImplicitParam(name = "X-Custom-Header", value = "A Custom Header", required = true, allowEmptyValue = false, paramType = "header", dataTypeClass = String.class, example = "my header example")
})
fun addJob(jobRequest: Job): ResponseEntity<*>{}
Theresatherese answered 27/11, 2018 at 17:49 Comment(1)
@ApiImplicitParams has been migrated to @Parameters springdoc.org/migrating-from-springfox.htmlNefertiti
R
20

I just added @RequestHeader(value="myHeader") String headerStr :

public ResponseEntity<User> saveNewUser(
        @RequestHeader(value="myHeader") String headerStr,
        @ApiParam(value = "the user to create", required = true) @RequestBody User user) throws RestServiceException {

    userService.save(user);
    return new ResponseEntity<User>(user, HttpStatus.OK);
}

(import org.springframework.web.bind.annotation.RequestHeader;)

You can also add a global header on every service in your documentation with the solution described here : Spring + Springfox + Header Parameters

Reynolds answered 25/11, 2016 at 9:22 Comment(0)
D
6

If you are having more header parameters, then every API will have that many @RequestHeader

To avoid this and your API looks simple you can use HeaderInterceptor to capture the header information.

In preHandle() ,  you need to extract the headerInfo in to a an Object and set it as RequestAttribute

  public class MyHeaderInterceptor extends HandlerInterceptorAdapter {

  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
        throws Exception { 

    HeaderVo headerVo = HeaderVo.createReqHeaderinput(
            request.getHeader("authorization"),
            request.getHeader("contentType"),                
            request.getHeader("myHeaderParam0"),
            request.getHeader("myHeaderParam1"), 
            request.getHeader("myHeaderParam3"),
            request.getHeader("myHeaderParam4"),
            request.getHeader("myHeaderParam5")

            );

     // You can do any validation of any headerInfo here.
     validateHeader(headerVo);

     request.setAttribute("headerName", headerVo);
     return true;
   }

 }

Your API will looks like the below with a @RequestAttribute("headerName")

public @ResponseBody
ResponseEntity<MyResponse> getSomeApi(
        //Headers common for all the API's       

        @RequestAttribute("headerName") HeaderVo header ,
        @ApiParam(value = "otherAPiParam", required = true, defaultValue = "") 
        @PathVariable(value = "otherAPiParam") String otherAPiParam,
        @ApiParam(value = "otherAPiParam1", required = true, defaultValue = "") 
        @RequestParam(value = "otherAPiParam1") String otherAPiParam1,
        @ApiParam(value = "otherAPiParam2, required = true, defaultValue = "")
        @RequestParam(value = "otherAPiParam2") String otherAPiParam2
     ) throws MyExcp  {
  ....
 }

Your Swagger still should describes all headers of the API, for that you can add parameters in swagger Docket, SwaggerConfig Please note ignoredParameterTypes, we mentioned to ignore HeaderVo, because that is internal to the application. swagger doesnt require to show that

@Bean
public Docket postsApi() {

    //Adding Header
    ParameterBuilder aParameterBuilder = new ParameterBuilder();
    List<Parameter> aParameters = new ArrayList<Parameter>();

    aParameters.clear();

    aParameterBuilder.name("myHeaderParam0").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
    aParameters.add(aParameterBuilder.build());
    aParameterBuilder.name("myHeaderParam1").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
    aParameters.add(aParameterBuilder.build());
   ....
   ....

    return new Docket(DocumentationType.SWAGGER_2).groupName("public-api")
            .apiInfo(apiInfo()).select().paths(postPaths()).build().ignoredParameterTypes(HeaderVo.class).globalOperationParameters(aParameters);

   }
Doelling answered 26/4, 2018 at 15:40 Comment(0)
U
0

sujith kasthoori's answer is the correct answer if one wants to send a header key-value from swagger UI for every end point. Its just the case that ParameterBuilder & Parameter are deprecated now.

List<RequestParameter> globalRequestParameters = new ArrayList<>();
    RequestParameterBuilder customHeaders = new RequestParameterBuilder();
    customHeaders.name("X-TenantID").in(ParameterType.HEADER)
        .required(true)
        .build();

Above is for when a header parameter named "X-TenantID" is mandatory to be sent with every request.

Then it needs to be added to Docket definition , .globalRequestParameters(globalRequestParameters)

enter image description here

Unguent answered 28/7, 2022 at 11:21 Comment(0)
A
0

its working fine for me

 public Docket productApi() {       
        List<RequestParameter> globalRequestParameters = new ArrayList<>();
         RequestParameterBuilder customHeaders = new RequestParameterBuilder();
         RequestParameter requestParameter=  customHeaders.name("token").in(ParameterType.HEADER)
            .required(true)
            .build();
              
            
        return new Docket(DocumentationType.SWAGGER_2)               
                .securityContexts(Arrays.asList(securityContext()))
                
                .globalRequestParameters(globalRequestParameters)
                .select()
                
                .apis(RequestHandlerSelectors.basePackage("com.productcatalogue.rest"))
                
                .paths(PathSelectors.any())
                
                .build();
   }
Avi answered 18/4 at 10:2 Comment(3)
why you left commented code and how is it helpful to the OP?Winslow
@banan3'14 u can ignore it. this was used for auth2 token configuration in swagger . now we removed the api authorizationAvi
@Guarav put some effort to tidy up the answer. Remove the commented code if it's useless. Remember that your code will be read multiple times and you waste a lot more time leaving dead code than just removing itWinslow

© 2022 - 2024 — McMap. All rights reserved.