Dherik
Dherik

Reputation: 19110

How document an API that produces a file (pdf) for download on Swagger?

I'm trying to discover some way to document an API that returns a PDF (or any other file) to download.

Using Spring, my Rest resource is like this:

@Override
@GetMapping(produces = "application/pdf")
public ResponseEntity<InputStreamResource> find(
        @PathVariable long id
) {

    Result result = service.find(id);

    HttpHeaders headers = disableCache();

    return ResponseEntity
            .ok()
            .headers(headers)
            .contentLength(result.getSize())
            .contentType(MediaType.parseMediaType("application/pdf"))
            .body(new InputStreamResource(result.getFileInputStream()));
}

This works very well to download the file. But I don't know the good practice to document the response using Swagger.

Actually, I tried that with Swagger annotations:

@ApiOperation(value = "Some description")
@ApiResponses(value = {
        @ApiResponse(code = 200, message = "Success.")
})
@ResponseStatus(HttpStatus.OK)
@GetMapping(produces = "application/pdf")
ResponseEntity<InputStreamResource> find(
        @PathVariable long id
);

But the Swagger returns the content of InputStreamResource as Json on Swagger-ui, what is not the result.

How represent a file download on the response for Swagger?

Upvotes: 4

Views: 6055

Answers (2)

Lucos
Lucos

Reputation: 21

Let try to update your code like this:

  1. Update headers:
headers.add("Content-Type", "application/pdf");
headers.add("Content-Disposition", "attachment; filename=report.pdf");
  1. Use this annotation:
@ApiResponses(value = {
    @ApiResponse(code = 200, message = "Success.", response = byte.class)
})
  1. Update the pom:
<dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
            <exclusions>
                <exclusion>
                    <groupId>io.swagger</groupId>
                    <artifactId>swagger-annotations</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>io.swagger</groupId>
                    <artifactId>swagger-models</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>1.5.21</version>
        </dependency>
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-models</artifactId>
            <version>1.5.21</version>
        </dependency>

Hope it helps.

Upvotes: 2

whistling_marmot
whistling_marmot

Reputation: 3893

The annotations were ignored, but this worked for me:

TypeResolver typeResolver = new TypeResolver();
new Docket(DocumentationType.OAS_30)
    .alternateTypeRules(AlternateTypeRules.newRule(
        typeResolver.resolve(ResponseEntity.class, InputStreamResource.class),
        typeResolver.resolve(Byte.class), 
        DIRECT_SUBSTITUTION_RULE_ORDER));

Upvotes: 0

Related Questions