Sum
Sum

Reputation: 171

Swagger example post body - how to show JSON Body- Swagger-annotations

Requirement: I have a POST method which takes the input JSON as a String and passes it to another microservice. I don't want to create an Object (Bean) of this input JSON.

method:

    @ApiOperation(notes = "example" value = "/example", consumes = ".." , method= "..")
    @RequestMapping(name = "xxx" value ="/hello" ..)
    @ApiResponses(..)
        public @ResponseBody String getXXX (@Apiparam(name="JSONrequest", required = true) @RequestBody String JSONrequest){

    }

Problem: The generated Swagger doesn't show the input as a JSON model where all the JSON attributes are displayed.

Expectation: I want to display my Swagger Something like this :

enter image description here

Definately I am missing the key thing. Any thoughts?

Upvotes: 10

Views: 36363

Answers (4)

Praytic
Praytic

Reputation: 2071

Swagger @Operation annotation now has requestBody parameter. See: https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Annotations#requestbody

public Response updatePet(
      @RequestBody(description = "Pet object that needs to be added to the store", required = true,
                              content = @Content(
                                      schema = @Schema(implementation = Pet.class))) Pet pet) {
        //..
    }

Upvotes: 0

Panciz
Panciz

Reputation: 2234

It's an old question but since I haven't found a solution online here how I to customized the example value in the swagger documentation produce automatically by the java annotations. I use swagger 2.0 and springfox.version 2.10.5.

The Idea is documenting the class of the request parameter that has the @RequestBody annotation. for example my method is

    @ApiOperation(
              value = "Start ListBuilder extraction",
              response = ExtractionLogEntity.class,
              produces = "application/json"
            )
    @PostMapping("/extraction/start")
    public ExtractionLogEntity startTask(
        @RequestBody(required = true) ExtractionRequest request,

In order to expose request json object example I added a @ApiModelProperty(example = "...") annotation to the properties of ExtractionRequest .

   @ApiModelProperty(example = "[{ 'field':'value'}]")
    @NotNull
    private  List<ListBuilderFieldEntity> fields;

   @ApiModelProperty(example = "1000")

    private  String ied;
   @ApiModelProperty(example = "US")
    private  String codebase;

And that's the result

enter image description here

Upvotes: 4

Yogesh
Yogesh

Reputation: 11

I had the similar issue. My Service Class takes @RequestBody argument in String. So, what I did :

Created a POJO and used @RequestBody annotation with it instead of inputString.

  @RequestMapping(value = "/api/entity/{entityId}/user/query", method = {RequestMethod.POST}, produces = MediaType.APPLICATION_JSON_VALUE)
    public @ResponseBody
    ResponseEntity<String> queryUser(@PathVariable("entityId") String entityId,
                                      @RequestBody QueryUserJsonSchemaPOJO queryUserJsonSchemaPOJO, String inputString,
                                     HttpServletRequest request, HttpServletResponse response)
            throws Exception {
            return userService.queryUserService(inputString, entityId, request);
    }

Created an AOP with @Around annotation which update the inputString argument.

    @Around(value = "execution(* com.athmin.rest.UserController.*(..)) || execution(* com.athmin.rest.CityController.*(..)), and args(..) " +
                " && @annotation(com.athmin.annotations.JSONSchemaFileName) ")
        public Object validateRequestBodyAgainstJsonSchema(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    
        Object[] modifiedArgs = proceedingJoinPoint.getArgs();
        
        for (Object o : proceedingJoinPoint.getArgs()) {
                if (o instanceof HttpServletRequest) {
                    HttpServletRequest httpServletRequest = (HttpServletRequest) o;
                    requestBody = httpServletRequest.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
                }
            });
        
for (int i = 0; i < modifiedArgs.length; i++) {
            if (modifiedArgs[i] == null) { // Only inputString is null in my case
                modifiedArgs[i] = requestBody;
            }
        }
        
            proceedingJoinPoint.proceed(modifiedArgs);
    }

Upvotes: 1

Andrei Sfat
Andrei Sfat

Reputation: 8606

If changing from String to a concrete object is not okay (although that's what I would recommend you to do since it's cleaner), you can try using @ApiImplicitParams (check out their documentation)

@ApiOperation(notes = "example" value = "/example", consumes = ".." , method= "..")
@ApiImplicitParams({
        @ApiImplicitParam(name = "Object", value = "Object to be created", required = true, dataType = "your.package.BodyClass", paramType = "body")
})
@RequestMapping(name = "xxx" value ="/hello" ..)
@ApiResponses(..)
    public @ResponseBody String getXXX (@Apiparam(name="JSONrequest", required = true) @RequestBody String JSONrequest){

}

(not sure if you still need the @Apiparam(name="JSONrequest", required = true) bit from the method parameter)

Upvotes: 3

Related Questions