Making HTTP Requests in Ruby
Ruby comes with a powerful standard library for making HTTP requests: Net::HTTP. Whether you’re fetching data from an API, downloading files, or sending data to a webhook, Net::HTTP has you covered—no external gems required.
This guide walks you through common HTTP operations in Ruby, perfect for automation scripts and DevOps tasks.
Setting Up Your Request
Every HTTP request in Net::HTTP starts with creating a connection object. You’ll typically specify the host and port:
require 'net/http'
require 'uri'
uri = URI('https://api.github.com/users')
http = Net::HTTP.new(uri.host, uri.port)
For HTTPS, enable SSL:
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
The verify_mode setting controls SSL certificate verification. Use VERIFY_PEER for production (validates certificates) or VERIFY_NONE for development with self-signed certificates.
Making GET Requests
GET is the most common HTTP method—used to retrieve data. Here’s how to fetch data from an API:
require 'net/http'
require 'uri'
require 'json'
uri = URI('https://api.github.com/users/ruby')
response = Net::HTTP.get_response(uri)
puts response.code # => "200"
puts response.message # => "OK"
puts response.body # => JSON string with user data
For more control, use the request object directly:
require 'net/http'
require 'uri'
uri = URI('https://api.github.com/users/ruby')
request = Net::HTTP::Get.new(uri)
request['Accept'] = 'application/vnd.github.v3+json'
response = http.request(request)
data = JSON.parse(response.body)
puts data['login'] # => "ruby"
The Net::HTTP.get_response method is a convenience shortcut that creates the request automatically. For adding headers or fine-tuned control, create the request object explicitly.
Making POST Requests
POST requests send data to a server—useful for creating resources, submitting forms, or sending JSON to an API:
require 'net/http'
require 'uri'
require 'json'
uri = URI('https://httpbin.org/post')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Content-Type'] = 'application/json'
request.body = JSON.generate({ name: 'Ruby', type: 'language' })
response = http.request(request)
puts response.code # => "200"
puts response.body # => Echoed JSON response
The request object gives you full control over the HTTP method, headers, and body. Use JSON.generate to convert a Ruby hash to a JSON string.
Working with Headers
Headers provide metadata about your request. Common headers include:
request = Net::HTTP::Get.new(uri)
# Authentication
request['Authorization'] = 'Bearer YOUR_TOKEN'
# Content type
request['Content-Type'] = 'application/json'
# Accept response format
request['Accept'] = 'application/json'
# Custom headers
request['X-Custom-Header'] = 'MyValue'
response = http.request(request)
Headers are case-insensitive in HTTP, but Ruby uses the capitalization you provide. Stick to the standard formats shown above for compatibility.
Handling Responses
Net::HTTP provides several ways to work with responses:
response = http.request(request)
# Check status code
if response.code == '200'
puts 'Success!'
end
# Parse JSON response
data = JSON.parse(response.body)
# Read response header
puts response['Content-Type'] # => "application/json"
# Response object methods
puts response.content_type
puts response.content_length
puts response['Set-Cookie']
The response object provides access to the status code via code (string) or integer_code (integer), the message via message, and the body via body.
Error Handling
Network requests can fail—servers go down, timeouts happen, SSL errors occur. Always handle exceptions:
require 'net/http'
require 'uri'
def fetch_url(url)
uri = URI(url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.open_timeout = 5 # Connection timeout
http.read_timeout = 10 # Read timeout
request = Net::HTTP::Get.new(uri)
begin
response = http.request(request)
case response
when Net::HTTPSuccess
response.body
when Net::HTTPRedirection
# Follow redirect
fetch_url(response['Location'])
else
puts "Error: #{response.code} #{response.message}"
nil
end
rescue Net::OpenTimeout => e
puts "Connection timeout: #{e.message}"
nil
rescue Net::ReadTimeout => e
puts "Read timeout: #{e.message}"
nil
rescue OpenSSL::SSL::SSLError => e
puts "SSL error: #{e.message}"
nil
rescue SocketError => e
puts "DNS or connection error: #{e.message}"
nil
end
end
Key timeouts to set:
open_timeout— seconds to wait when connectingread_timeout— seconds to wait for data after connected
Practical Examples
Downloading a File
require 'net/http'
require 'uri'
uri = URI('https://example.com/large-file.zip')
response = Net::HTTP.get_response(uri)
if response.code == '200'
File.write('large-file.zip', response.body)
puts 'File downloaded successfully!'
end
Checking API Availability
require 'net/http'
require 'uri'
def api_healthy?(url)
uri = URI("#{url}/health")
response = Net::HTTP.get_response(uri)
response.code == '200'
end
puts api_healthy?('https://api.example.com') # => true or false
Sending Webhook Notifications
require 'net/http'
require 'uri'
require 'json'
def send_webhook(url, payload)
uri = URI(url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Content-Type'] = 'application/json'
request.body = JSON.generate(payload)
http.request(request)
end
send_webhook('https://hooks.example.com/notify',
{ event: 'deploy', status: 'success', service: 'my-app' })
Query String Parameters
require 'net/http'
require 'uri'
# Build URL with query parameters
params = { page: 1, per_page: 50, sort: 'desc' }
uri = URI('https://api.example.com/items')
uri.query = URI.encode_www_form(params)
response = Net::HTTP.get_response(uri)
The encode_www_form method properly encodes query parameters, handling special characters and multiple values.
When to Use Net::HTTP
Net::HTTP is ideal for:
- Simple API calls in scripts
- Automation and DevOps tasks
- Learning how HTTP works
- Lightweight integrations with no dependencies
For more complex needs, consider these gems:
- Faraday — unified interface with multiple adapters (Net::HTTP, HTTPClient, Patron)
- HTTParty — convenient DSL for REST APIs with automatic JSON parsing
- RestClient — simple Ruby-like HTTP client interface
Summary
Ruby’s Net::HTTP library gives you everything needed for HTTP scripting:
- Simple GET and POST requests
- Full control over headers and body
- SSL/TLS support for secure connections
- Proper error handling for production scripts
- No external dependencies required
Start with require 'net/http' and you’re ready to make HTTP requests from any Ruby script.