What is the syntax for making multipart requests with HTTParty?

Overview

HTTParty is a popular Ruby gem for making HTTP requests. Multipart requests are essential for uploading files and submitting form data with mixed content types. HTTParty provides multiple approaches for handling multipart requests, from simple file uploads to complex form submissions.

Basic Multipart Request Syntax

The fundamental syntax for multipart requests in HTTParty uses the multipart: true option:

require 'httparty'

response = HTTParty.post(
  'https://api.example.com/upload',
  body: { 
    field1: 'value1',
    file: File.open('document.pdf')
  },
  multipart: true
)

Simple File Upload

The most straightforward approach for uploading a single file:

require 'httparty'

# Upload a single file with form data
response = HTTParty.post(
  'https://httpbin.org/post',
  body: {
    'description' => 'My uploaded file',
    'category' => 'documents',
    'file' => File.open('example.pdf', 'rb')
  },
  multipart: true
)

puts response.code
puts response.body

Multiple File Upload

To upload multiple files in a single request:

require 'httparty'

files = [
  File.open('document1.pdf', 'rb'),
  File.open('image.jpg', 'rb'),
  File.open('data.csv', 'rb')
]

response = HTTParty.post(
  'https://api.example.com/upload',
  body: {
    'project_name' => 'My Project',
    'files' => files
  },
  multipart: true
)

# Don't forget to close the files
files.each(&:close)

Advanced Multipart with MIME Types

For more control over file uploads, you can specify MIME types explicitly:

require 'httparty'
require 'mime/types'

# Determine MIME type automatically
file_path = 'example.png'
mime_type = MIME::Types.type_for(file_path).first&.content_type || 'application/octet-stream'

file = File.open(file_path, 'rb')

body = {
  'title' => 'Image Upload',
  'tags' => 'photo,example',
  'image' => HTTParty::Request::Multipart::File.new(file, mime_type, File.basename(file_path))
}

response = HTTParty.post(
  'https://api.example.com/images',
  body: body,
  multipart: true
)

file.close

Multipart with Custom Headers

You can add custom headers to multipart requests:

require 'httparty'

response = HTTParty.post(
  'https://api.example.com/upload',
  body: {
    'metadata' => '{"version": "1.0"}',
    'file' => File.open('data.json', 'rb')
  },
  headers: {
    'Authorization' => 'Bearer your-token-here',
    'X-Custom-Header' => 'custom-value'
  },
  multipart: true
)

Working with StringIO

For uploading content that's not stored as files:

require 'httparty'
require 'stringio'

# Create content in memory
csv_content = "name,email\nJohn,john@example.com\nJane,jane@example.com"
csv_io = StringIO.new(csv_content)

response = HTTParty.post(
  'https://api.example.com/import',
  body: {
    'format' => 'csv',
    'data' => HTTParty::Request::Multipart::File.new(csv_io, 'text/csv', 'data.csv')
  },
  multipart: true
)

Error Handling

Always include proper error handling for multipart requests:

require 'httparty'

begin
  file = File.open('large-file.zip', 'rb')

  response = HTTParty.post(
    'https://api.example.com/upload',
    body: {
      'file' => file,
      'checksum' => Digest::MD5.hexdigest(file.read)
    },
    multipart: true,
    timeout: 300 # 5 minutes for large files
  )

  if response.success?
    puts "Upload successful: #{response.parsed_response}"
  else
    puts "Upload failed: #{response.code} - #{response.message}"
  end

rescue HTTParty::Error => e
  puts "HTTParty error: #{e.message}"
rescue StandardError => e
  puts "General error: #{e.message}"
ensure
  file&.close
end

Key Points to Remember

  1. Automatic Headers: HTTParty automatically sets the Content-Type header to multipart/form-data when multipart: true is used
  2. File Handling: Always close file handles after use to prevent resource leaks
  3. MIME Types: HTTParty can auto-detect MIME types, but you can specify them explicitly for better control
  4. Timeouts: Consider setting longer timeouts for large file uploads
  5. Error Handling: Always implement proper error handling for network operations

Installation

Ensure you have HTTParty installed:

gem install httparty

# Or add to your Gemfile
gem 'httparty'

For MIME type detection, also install:

gem install mime-types

Related Questions

Get Started Now

WebScraping.AI provides rotating proxies, Chromium rendering and built-in HTML parser for web scraping
Icon