utkarsh31
utkarsh31

Reputation: 1549

Swagger datatype not generating docs

I have the below code in Swagger,

@Path("/v1")
    @ApiOperation(value = "POST - Some Value", nickname = "post-funtion", consumes = "application/json", produces = "text/html; charset=UTF-8", tags = {
            "Some Controller" })
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", paramType = "header", dataType = "string", format = "JWT", required = false, value = "A User Service JWT"),
            @ApiImplicitParam(name = "Request", value = "Request Object", paramType = "body", dataType = "org.pkg.SomeRequest", required = true) })
    @ApiResponses({
            @ApiResponse(code = 200, message = "Value Added", response = SomeResponse.class) })
private Object retrieveByName(Request request, Response response)
{
    return new RetrieveByNameRqstHandler(catalogService, request, response).handle();
}

The code is supposed to automatically generate default json request depending upon the datatype which in this case is "org.pkg.SomeRequest" but there is nothing generated. On the contrary if I change the "org.pkg.SomeRequest" with "org.pkg.SomeResponse" there is a default JSON generated for this. Can anybody help me please?

Consider both classes SomeRequest,SomeResponse have the same code. This is the image where I use "org.pkg.SomeRequest" in the dataType This is the image where I use <code>"org.pkg.SomeRequest"</code> in the dataType This is the image where I use <code>"org.pkg.SomeResponse"</code> in the dataType

This is the image where I use "org.pkg.SomeResponse" in the dataType

Upvotes: 1

Views: 6599

Answers (3)

alex90bar
alex90bar

Reputation: 111

I faced the same problem with ApiImplicitParam, and after 2 hours of app rebuilding I found out one more solution))

It doesn't look very logical, but it works:

@ApiOperation(value = "Запрос...", response = Request.class)
    @ApiImplicitParams({
       @ApiImplicitParam(name = "request", value = "DTO Запрос...", required = true, 
    dataType = "Request", dataTypeClass = Request.class, paramType = "body")
    })
    @ApiResponses(value = {
        @ApiResponse(code = 200, message = "Успешный запрос", response = Response.class),
        @ApiResponse(code = 400, message = "Ошибка в запросе"),
        @ApiResponse(code = 500, message = "Внутренняя ошибка сервера")
    })
    public Response processRequest(@ApiParam(hidden = true)
    @RequestBody Object request) {
            return service.processRequest(request);
    }

The key is to set the class of your request DTO in @ApiOperation response field, and at the same time to set @ApiResponses group of annotations.

It seems it helps swagger to detect the type of request correctly. And response is being displayed correctly by swagger as well:

enter image description here

But of course when I found the solution posted by @danidacila I've used it in my app, because it looks much more preferrable and smart and it works as well.

Upvotes: 0

danidacila
danidacila

Reputation: 157

ApiImplicitParam can map a parameter to a correct type, but the type must be detected by swagger, so must be a valid reference. The only way I could make this working is by using additionalModels method.

Example in spring-boot:
configure swagger

import springfox.documentation.spring.web.plugins.Docket;
import com.fasterxml.classmate.TypeResolver;
...

@Bean
public Docket api(TypeResolver typeResolver) {
  return new Docket(DocumentationType.SWAGGER_2)
    .groupName("your-group-rest-api")
    .select()
    .apis(RequestHandlerSelectors.basePackage("your.package"))
    .paths(PathSelectors.any())
    .build()
    .additionalModels(typeResolver.resolve(YourModel.class))
    .apiInfo(apiInfo());
}

controller

@ApiOperation...
@ApiImplicitParams(
  @ApiImplicitParam(dataType = "YourModel", name = "requestJson", paramType = "body"))
@ApiResponses...
@RequestMapping...
public void yourMethod(@RequestBody String requestJson,...)

Of course, you could have an InputStream parameter for the request and map that to your model.

Upvotes: 1

Vinicius de Almeida
Vinicius de Almeida

Reputation: 111

According to this GitHub issue on Swagger core project, if you add the annotation @ApiImplicitParam should resolve your problem.

@ApiImplicitParams({
    @ApiImplicitParam(
        required = true,
        dataType = "com.example.SomeObjectDto",
        paramType = "body"
    )
})

But normally if you just add the class on your method signature it'll work.

private Object retrieveByName(SomeObjectDto someObjectDto) {
    someCode();
}

Also SomeObjectDto class should contain "get" methods for your variables like.

class SomeObjectDto {
    private String info;

    getInfo(){
        return info;
    }
}

Will produce the following JSon.

{ info: "string" }

Upvotes: 2

Related Questions