web-dev-qa-db-fra.com

Ajouter un paramètre d'en-tête dans la documentation de Swagger UI avec Springfox

Je veux ajouter un champ de paramètre d'en-tête dans la documentation de l'interface utilisateur swagger générée automatiquement de mon service de repos. J'utilise Spring et 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);
}

Comme vous le voyez, j'ai déjà un paramètre de type body. Je veux juste ajouter un en-tête type un.

7
Julien

Je viens d'ajouter @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;)

Vous pouvez également ajouter un en-tête global sur chaque service dans votre documentation avec la solution décrite ici: Spring + Springfox + Header Parameters

11
Julien

Je préfère utiliser @ApiImplicitParam après mon @RequestMapping plutôt que comme paramètres de fonction, car en général, vous pouvez traiter vos en-têtes dans un filtre (par exemple, l'authentification) et vous n'avez pas besoin des valeurs de cette méthode.

De plus, si vous en avez besoin dans la méthode, Swagger auto fournit le champ pour un @HeaderParam

Ce style améliore également la lisibilité et la flexibilité lorsque certains appels nécessitent des en-têtes et d'autres pas.

Exemple

@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<*>{}

Si tous ou la plupart de vos points de terminaison ont besoin d'un en-tête, je préfère le configurer comme vu ici

Si vous devez déclarer plusieurs paramètres d'en-tête, vous devez utiliser l'annotation @ApiImplicitParams:

@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<*>{}
13
Enoobong

Si vous avez plus de paramètres d'en-tête, alors chaque API aura autant de @RequestHeader

Pour éviter cela et votre API semble simple, vous pouvez utiliser HeaderInterceptor pour capturer les informations d'en-tête.

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;
   }

 }

Votre API ressemblera à ce qui suit avec un @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  {
  ....
 }

Votre Swagger devrait toujours décrire tous les en-têtes de l'API, pour cela vous pouvez ajouter des paramètres dans swagger Docket, SwaggerConfig Veuillez noter ignoredParameterTypes, nous avons mentionné d'ignorer HeaderVo, car cela est interne à l'application. swagger n'a pas besoin de montrer que

@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);

   }
4
sujith kasthoori