My Tangle with Excon
Alright, let’s talk about `excon`. I remember bumping into this thing a while back. I was knee-deep in some Ruby code, trying to fetch data from some API. You know how it is, the built-in `Net::HTTP` stuff feels like pulling teeth sometimes. Clunky. So, I went looking for something… simpler? Faster? I don’t know, just better.

Someone mentioned `excon`. Said it was fast, straightforward. Okay, fine. First step, like always, was chucking it into the Gemfile.
ruby
gem ‘excon’
Then the usual `bundle install`. No sweat there. That part’s always easy, right?
Next, I needed to actually use it. The basic examples looked simple enough. I just wanted to grab some JSON from a URL. So I tried something like this:

ruby
response = *(‘*/data’)
And bam, it worked. Mostly. Got a response object back. Okay, `*` gave me 200, good. `*` had the JSON string. Felt pretty direct, I’ll give it that. Less ceremony than `Net::HTTP`, for sure.
Going a Bit Deeper
But then things got a bit more involved. Needed to send some headers, you know, `Authorization` tokens and `Content-Type` stuff for POST requests.
- Figured out you just pass a `headers` hash. Okay, that makes sense.
- Needed query parameters? Add a `query` hash. Simple enough.
- POSTing data? Use `*` and pass a `body` parameter.
It felt pretty consistent. GET, POST, PUT, DELETE… they all followed a similar pattern. You give it the URL, then a hash with options like `:headers`, `:query`, `:body`, `:middlewares` (got into those later, bit more complex).

One thing I kinda liked was the persistent connection idea. If you’re hitting the same server over and over, `excon` can keep the connection open. Seemed smart for performance. Setting that up involved creating a connection object first:
ruby
connection = *(‘*’)
response = *(path: ‘/data’, query: { page: 1 })
response2 = *(path: ‘/data’, query: { page: 2 })

# …and so on
That felt a bit more organized than just firing off static `*` calls everywhere, especially in loops or when making multiple calls to the same API endpoint.
Where It Got Grindy
Now, it wasn’t all smooth sailing. Sometimes the error messages were… cryptic. You get some `Excon::Error::Socket` thing and you’re left scratching your head. Is it the network? Is it their server? Is it my code? Took some digging sometimes.
And the configuration! There are tons of options. Timeouts (`:read_timeout`, `:write_timeout`, `:connect_timeout`), SSL verification (`:ssl_verify_peer`), retries. It’s powerful, yeah, but sometimes it felt like too many knobs to fiddle with. I just wanted it to work reliably without needing a PhD in HTTP connection parameters.
I remember wrestling with SSL verification issues on some internal staging server with a self-signed certificate. Had to specifically tell `excon` to back off and not verify the peer (`ssl_verify_peer: false`). Felt dirty, but got the job done for testing.

So, What’s the Verdict?
Look, `excon` is solid. It’s generally fast, it’s pretty flexible, and once you get the hang of the options hash, it’s quite powerful. The persistent connection stuff is genuinely useful.
Is it my absolute favourite? Hard to say. Sometimes I reach for `HTTParty` just because its syntax feels a tiny bit more intuitive for super simple stuff, almost like using a browser from code. But when performance matters, or I need fine-grained control over the connection, timeouts, or retries, `excon` is definitely a strong contender. It feels more low-level, more bare-metal without being as painful as `Net::HTTP`.
So yeah, I used it, I wrestled with it a bit, but it mostly did what I needed. It’s in my toolbox. Sometimes it’s the right tool, sometimes another one feels better. That’s just how it goes, isn’t it?