cURL to Ruby Converter (Net::HTTP and Faraday)
Paste the curl command from an API doc and read it back as Ruby - a Net::HTTP call that needs no gems, and the Faraday equivalent for the connection your Rails app already has.
Your curl command
Ruby for this request
Net::HTTP (standard library, no gems)
uri = URI("https://api.example.com/v1/posts")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == "https"
request = Net::HTTP::Post.new(uri)
request["Content-Type"] = "application/json"
request["Authorization"] = "Bearer rb_live_9f2"
request.body = "{\"title\":\"Release notes\",\"published\":true}"
response = http.request(request)Faraday
conn = Faraday.new(url: "https://api.example.com")
response = conn.post("/v1/posts") do |req|
req.headers["Content-Type"] = "application/json"
req.headers["Authorization"] = "Bearer rb_live_9f2"
req.body = "{\"title\":\"Release notes\",\"published\":true}"
endWhat the conversion could not carry over
Everything runs in your browser. Nothing is uploaded.
What each curl flag becomes in Ruby
The conversion reads the flags an API doc usually ships and nothing else. -X sets the verb, which picks the request class - Net::HTTP::Get, Post, Put, Patch, Delete or Head - and the matching Faraday method; with no -X the verb is GET, or POST as soon as there is a body, exactly as curl decides it. Each -H becomes a request["Name"] = "value" line, or a req.headers["Name"] assignment inside the Faraday block, with the name and the value split on the first colon. Every -d, --data-raw and --data-binary is concatenated with an ampersand the way curl concatenates them, and the result is assigned to the body verbatim - no re-encoding, so a JSON payload stays the JSON you pasted. -u becomes request.basic_auth("user", "pass") and f.request :authorization, :basic on the Faraday connection, rather than a hand-built header. -b becomes a Cookie header, -I sets HEAD, and the flags that only change what curl prints - -s, -v, -i, --compressed - are dropped, because they describe a terminal rather than a request. Anything left over is listed under the snippets instead of being guessed at.
Net::HTTP or Faraday in a Rails app
Net::HTTP is in the standard library, so the first snippet runs in a fresh Rails app with nothing added to the Gemfile. That is the whole argument for it: one call to a webhook, a health probe, a script that runs once a night. The cost shows up on the second and third call - you are assigning headers by hand, checking the response class yourself, and parsing the body at every call site. Faraday earns its place when the calls become a client. A connection is built once, with a base URL, the auth and the default headers on it, and the per-request block only carries what actually changes. Middleware then moves the repetitive parts out of the call site - JSON request and response encoding, retries with backoff, redirects, instrumentation - and because Faraday keeps the adapter separate you can swap Net::HTTP for something else without touching the calls. In practice a Rails app tends to start with the first snippet and move to the second the day a second endpoint appears on the same host.
Redirects, timeouts and TLS in Ruby
Three defaults differ from curl's and all three bite in production. Net::HTTP does not follow redirects, so where curl -L quietly lands on the new URL, Ruby hands you a Net::HTTPRedirection and nothing else happens; Faraday behaves the same until faraday-follow_redirects is in the stack. Timeouts are the second: Net::HTTP will wait 60 seconds to open a connection and 60 more to read, which is long enough to hold a web request or a job worker hostage, so set http.open_timeout and http.read_timeout - or Faraday's options.timeout and options.open_timeout - to something a caller can live with. TLS is the third, and the one worth leaving alone: http.use_ssl is set from the scheme above, the certificate is verified against the system store, and curl -k has no place in a deployed app. If a call can be slow or can fail, it belongs in an Active Job with a retry policy rather than in a controller action, so a request that times out costs a queued job rather than a user's page.