How to send a file in the response via Grape API in Rails

How to send a file as a response in the API using Ruby on Rails. Do you have a requirement to upload file via Grape? Here's an example for you to understand better.

Posted by Ameena on 16 Apr 2020

Consider reading this blog if you are wondering how to send a file as a response in the API using Ruby on Rails.

As an example, I have considered sending a zip file for which I have used a gem rubyzip

After you have a file ready that needs to be sent, you will have to describe three things in your code for Rails to understand what needs to be sent to the recipient.

  • Content-Type

    HTTP response that we are sending should include the Content-Type header field which indicates the media type of the body.

  • Content-Disposition

    HTTP response should include the Content-Disposition response header that indicating if the content is expected to be displayed inline in the browser, or as an attachment.

  • API format

    The API to support the :binary content-types. By using :binary there will be no formatter, data will be returned "as is".

# users.rb
...
get :zipped_media_files do
  user = User.find(params[:id])
  directory_to_zip = "#{Rails.root}/tmp/#{user.full_name}"
  Dir.mkdir(directory_to_zip)
  zip_file_name = "#{Rails.root}/tmp/#{user.full_name}.zip"
  user.file_attachments.each do |file_attachment|
    url = file_attachment.file.url
    file_path = url.match(/\.com\/([^\?]*)/)[1]
    file_name = File.basename(file_path)
    File.open("#{Rails.root}/tmp/#{user.full_name}/#{file_name}", "wb") do |f|
      f << open(url).read
    end
  end
  files = Dir.entries(directory_to_zip) - %w( . .. )
  Zip::File.open(zip_file_name, ::Zip::File::CREATE) do |zipfile|
    files.each do |file|
      zipfile.add(file, "#{Rails.root}/tmp/#{user.full_name}/#{file}")
    end
  end
  content_type "application/octet-stream"
  header['Content-Disposition'] = "attachment; filename=#{user.full_name}.zip"
  env['api.format'] = :binary
  File.open(zip_file_name, 'rb').read
end

Keep Coding !!!

Contact us to work on your website.

- Ameena


Have a Project in mind?