Networking and HTTP

36.1 Net::HTTP

require "net/http"
require "json"

uri = URI("https://jsonplaceholder.typicode.com/posts/1")
response = Net::HTTP.get_response(uri)
puts response.code, JSON.parse(response.body)["title"] if response.is_a?(Net::HTTPSuccess)

Net::HTTP.start(uri.host, uri.port, use_ssl: true, open_timeout: 5, read_timeout: 10) do |http|
  req = Net::HTTP::Post.new("/posts", "Content-Type" => "application/json", "Authorization" => "Bearer token")
  req.body = { title: "Hello", body: "From Ruby", userId: 1 }.to_json
  res = http.request(req)
  puts res.code, res.body
end

Net::HTTP.post(URI("https://httpbin.org/post"), { a: 1 }.to_json, "Content-Type" => "application/json")

36.2 HTTP Client Gems

Middleware-based, adapter-agnostic (retry, logging, JSON) Simple class-based API Fast, chainable API Parallel requests via libcurl Fiber-based async HTTP/1/2 Fast, persistent connections

require "faraday"
conn = Faraday.new(url: "https://api.github.com") do |f|
  f.request :json
  f.response :json
  f.response :raise_error
  f.request :retry, max: 3, interval: 0.5
end
repo = conn.get("/repos/ruby/ruby").body
puts repo["stargazers_count"]

36.3 Sockets and Servers

Others: open-uri (URI.open(url).read), WebSockets (faye-websocket, async-websocket), SMTP (the mail gem), FTP (net-ftp gem), SSH (net-ssh), DNS (Resolv), gRPC (the grpc gem).

require "socket"
server = TCPServer.new(9000)
loop do
  Thread.start(server.accept) do |client|
    line = client.gets
    client.puts "Echo: #{line}"
    client.close
  end
end
# Client: s = TCPSocket.new("localhost", 9000); s.puts "hi"; s.gets