Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return a pdf file from a rest api?

I have setup a rest API inside a ruby on rails application, I now have a requirement to generate a PDF and return this PDF from a get request. I am looking for some advice on how to implement this feature.

Some of the requirements that I have are as follows: I can't save the file and give the end user a link to the file because the data in the file can be updated at any time. I am using the application as microservice so there isn't a front end that I can use to display the file.

So here is my thinking I would love some advice on how to implement this feature.

I would like to make a get request to a specific endpoint in the application. I expect a PDF file to be returned which I can then display to the end user.

I am currently using WickedPdf gem to generate a temporary PDF file, but I am really struggling with how the response should look.

Any advice would be much appreciated.

like image 498
Andrew_tainton Avatar asked Mar 15 '17 09:03

Andrew_tainton


1 Answers

One way is to create a PDF file in memory and stream it to the client. I prefer this way, maybe later you will have to send PDF files via email, or just save them to some backup disk etc...

def get_pdf
  pdf = WickedPdf.new.pdf_from_string('<h1>Hello There!</h1>')
  send_data pdf, filename: 'file_name.pdf'
end

You can put the PDF generation to a different service and just call it in the controller. This provides isolation and you can test it separately.

Also you can debug the endpoint response with HTTPie http get http://localhost:3000/invoices/1/get_pdf

Rails will set all the necessary HTTP response headers:

Content-Disposition: attachment; filename="file_name.pdf"
Content-Length: 5995
Content-Transfer-Encoding: binary
Content-Type: application/pdf

So when the user clicks on a link that points to the endpoint, most probably the download dialog will pop up because of the Content-Disposition: attachment; header

Other solution is to render the get_pdf.html as PDF and send back to the client:

def get_pdf
  render pdf: "file_name"
end

But in this case the Content-Disposition header will be inline, which means the browser will open the pdf (if it can read PDF format) instead of offering to download it.

like image 59
Peter Toth Avatar answered Nov 16 '22 22:11

Peter Toth