question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Can't find a way to return a pdf binary

See original GitHub issue

Sorting

  • I’m submitting a …

    • bug report
    • feature request
    • support request
  • I confirm that I

    • used the search to make sure that a similar issue hasn’t already been submit

Expected Behavior

I’d like to return a PDF from an endpoint and have the Swagger UI reflect the Media Type for that endpoint is " application/pdf".

"/document": {
  "get": {
    "operationId": "Get",
    "responses": {
      "200": {
        "description": "Ok",
        "content": {
          "`application/pdf`": {
            "schema": {
              "type": "string",
              "format": "byte"
            }
          }
        }
      }
    },
  }
}

ℹ️I don’t know swagger spec very well so I’m just guessing above that I’d like content to be application/pdf

Current Behavior

I’ve tried a plain return, e.g. the controller looks like this:

  @Get("/")
  public async getDocument(
  ): Promise<Readable> {
    const buffer = Buffer.from(readFileSync(join(__dirname, "minimal.pdf")));
    return Readable.from(buffer);
  }

This works ✅, but in Swagger UI the Media Type is application/json

I’ve also tried using a TsoaResponse pattern, like this:

  @Get("/")
  public async getDocument(
    @Res() res: TsoaResponse<200, Readable, { "content-type": "application/pdf" }>
  ): Promise<void> {
    const buffer = Buffer.from(readFileSync(join(__dirname, "minimal.pdf")));
    await res(200, Readable.from(buffer), {
      "content-type": "application/pdf",
    });
  }

This also works ✅, but the Swagger UI says application/json ❌ the UI show two responses: One 200, and one 204 (b/c of the void return) ❌

"/documents": {
  "get": {
    "operationId": "Get",
    "responses": {
      "200": {
        "description": "",
        "content": {
          "application/json": {
            "schema": {
              "type": "string",
              "format": "byte"
            }
          }
        },
        "headers": {
          "content-type": {
            "schema": {
              "type": "string",
              "enum": [
                  "application/pdf"
              ],
              "nullable": false
            },
            "required": true
          }
        }
      },
      "204": {
        "description": "No content"
      }
    },
  }
}

Steps to Reproduce

Download this example pdf file: https://brendanzagaeski.appspot.com/minimal.pdf

Add this route:

import { Readable } from "stream";
import {
  Controller,
  Get,
  Route,
} from "tsoa";


@Route("document")
export class DocumentController extends Controller {
  @Get("/1") public async getDocument1(
  ): Promise<Readable> {
    const pdfBuffer = Buffer.from(readFileSync(join(__dirname, "minimal.pdf")))
    return Readable.from(buffer);
  }
}

@Route('document')
export class DocumentController extends Controller {
  @Get('/2')
  public async getDocument2(@Res() res: TsoaResponse<200, Readable, { 'content-type': 'application/pdf' }>): Promise<void> {
    const pdfBuffer = Buffer.from(readFileSync(join(__dirname, 'minimal.pdf')))
    return Readable.from(buffer)
  }
}

Context (Environment)

Version of the library: tsoa@3.11.2 Version of NodeJS: v16.1.0

  • Confirm you were using yarn not npm: [😬] (I’m using pnpm, hope that’s not a problem!)

Detailed Description

I’m too new to TSOA + OpenAPI to make a truly specific proposal, but I think I expected either a content-type decorator or some way to use TsoaResponse to specify that this endpoint’s only response is a PDF binary.

And thanks for making tsoa available!

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:5

github_iconTop GitHub Comments

1reaction
WoHcommented, Sep 29, 2021

Sounds like this duplicates #968?

Yes, that’s how we should support it.

0reactions
Scarbouscommented, Jun 3, 2022

I use tsoa with express.

The express router from tsoa calls pipe if the Object has the right properties. https://github.com/lukeautry/tsoa/blob/master/packages/cli/src/routeGeneration/templates/express.hbs#L210

My current solution is to an Object like:

this.setHeader('Content-type', 'application/pdf');

return {
  readable: true,
  _read: () => { },
  pipe: (res: Response) => { res.end(buffer, 'binary') }
};
Read more comments on GitHub >

github_iconTop Results From Across the Web

What is the right way to return a binary PDF from Springboot ...
I found that just returning raw "byte[]" from my resource method makes it work, or a raw Response holding byte[] content. still strange...
Read more >
Can't find a way to return a pdf binary - Lukeautry/Tsoa - Codesti
I'd like to return a PDF from an endpoint and have the Swagger UI reflect the Media Type for that endpoint is "...
Read more >
Unable to load file in binary format #837 - GitHub
Iam trying to load a pdf file from an API response which is binary I believe, as it starts with %PDF when opened...
Read more >
Attaching Portable Document Format (PDF) files to e-files
Steps to attach PDFs · In UltraTax CS, choose Edit > Electronic Filing Attachments. · Click the Add button. · In the Product...
Read more >
How do i fix "A binary attachment submitted in the PDF format ...
Entering the DETAIL data precluded this requirement and the IRS accepted by tax return. Long answer: forms 1099B are the culprit: After much ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found