Httpx: A Ruby HTTP library
gitlab.com
gitlab.com
page1, page2, ... = HTTPX.get("/page1", "/page2", ...)
Why encode parallelism into a single polymorphic function? Why not use composition instead? Now you're stuck with this API forever. And if you want to customize parallel fetches (eg: batching) you'll need another different looking API.The API was not a question of preference. If you look at most http lib APIs (python requests included), a single call returns a response object. My goal was to keep compatibility with this API to ease the migration effort, while baking in support for concurrent requests, which was the whole point of the lib.
There is no parallelism in that call btw. It's in the Readme. If it's http/2, it'll multiplex requests. If it's http/1, it'll try to pipeline, and if doesn't work, it'll fetch them one by one (with or without keep-alive). If they're different origins, the requests will be managed inside an event loop.
> Why not use composition instead?
You'll have to explain with an example of your own. However, there's already a ticket for implementing an event-based request handling, I just never prioritized it because no one asked for it yet, no one has shown interest in contributing, and frankly, I haven't needed it yet.
> Now you're stuck with this API forever.
It's still early 0.x days, so I might still remove APIs I don't think are future proof. That said, a lot of libs have lived with similar APIs all these years, and I don't see any reason for removing it.
Do you plan to support webmock and httplog ? Or add support for httpx into those ?
Can't integrate a networking lib that can't be mocked in my specs.
httpx also ships with its own request/response logger, set HTTPX_DEBUG=1 or set the options so that you see an example.
Any idea why the project is posted now? Is there a beta or RC release that’s significant?
responses = HTTPX.get("/page1").
get("/page2").
start
My guess is that the focus of HTTPX being parallel requests, the author choose an API that explicitly groups them together. The documentation is pretty sparse, I wonder if we can pass an array of URLs to get(). array = ["https://news.ycombinator.com/news", "https://news.ycombinator.com/news?p=2", "https://news.ycombinator.com/news?p=3"]
page1, page2, page3 = HTTPX.get(*array) *pages = HTTPX.get(*urls) urls = ['https://example.com/foo', 'https://example.com/bar']
HTTPX.get(*urls)Timeout does not help here - if the api is for concurrent requests, it's bad that caller cannot do anything before `(the slowest request finished || timeout exceeded)`.
It’s interesting to see that the Ruby ecosystem doesn’t seem to find its “requests” library. There is so many very good competitive libraries: native net/http, HttpClient by Nahi, http.rb, HttpParty, RestHttp, RestClient, excon, em-http, faraday, curb, etc., and now Httpx!
It's also based on Curl so very stable.
https://github.com/typhoeus/typhoeus
hydra = Typhoeus::Hydra.new
10.times do
request = Typhoeus::Request.new("www.example.com", followlocation: true)
request.on_complete do |response|
#do_something_with response
end
hydra.queue(request)
end
hydra.runAm I right to assume the primary difference with this library is concurrent connections?
httpx is more than concurrent connections. It's actually about concurrent requests done right, advanced http features (it can do connection coalescing, alt-svc), and it comes with a baked-in plugin system which makes it easy to extend.
Go through the wiki and give it a try when you can.
Eg. the name came from a totally unrelated discussion, and research did not yield results about Ruby's counterpart back then [0].
In fact, Python HTTPX started with requests-async [1], which was then spun up into httpcore, which was then renamed to http3, and finally HTTPX.
Still very funny to me that these two projects (Python HTTPX and Ruby HTTPX) have so much in common: HTTP/2 support, API compatibility with the current de-facto HTTP library of the language, etc.
[0]: https://github.com/python-http/discussions/issues/1#issuecom...
Good luck in our work!
People develop other HTTP packages usually for ergonomic reasons, but the HTTP from core Ruby works fine.
Requesting a DNS-server for a SRV-record gives you a prioritised list of IPs and ports, and it is up to the implementor to pick the right one.
As it works currently you would have to do a lookup, pick a endpoint, and then feed it into your HTTP library or TCP library.
This is fine in code that you control, but there are so many libraries out there that expects a hostname or an IP-address with a port number, and in a highly containerised world endpoints are more short lived than ever, so we need retry mechanics as well: Try the next server:port pair in the prioritized list.
Although choice and experimentation certainly has its value, I'm curious to hear if there was any attempt to build the missing features into any of the existing libraries? (for example excon or http.rb which this is based on)
Kudos to the author(s).
Faraday would likely need some modification to support the concurrency aspect, but eventually you could be using Faraday _with_ httpx, rather than instead of.
I think gitlab's sidebar is probably not helping with my association, it's too similar to bitbucket or other "enterprise-y" type websites.
[EDIT] I also assume a higher likelihood that key persons on the project are the contrarian-for-contrary's-sake sort if they're not on GH. Not that it's certain, mind, but that it's a bit more likely.
Not browsing the repository / looking at a file? Can't go to the "jump to file" page.
Not at the root of a repository? Can't access releases.
Their "mobile UI" (which, I think, is being rehauled?)
Or maybe it's just inevitable that what was once distributed always becomes centralized again? (To that end I'm reminded of the book The Master Switch by Tim Wu. He discusses similar cycles happening to various "information empires".)
[1]: https://news.ycombinator.com/item?id=21395629 [2]: https://news.ycombinator.com/item?id=21025037
I also decided to close-source this project initially, as I didn't know where it was headed, and github didn't provide private repositories at the time.
It also provided CI out-of-the-box, whereas if I had chosen github, I'd have to integrate it with travis, or circle-ci, or yet another third-party that required me to update my configs every 6 months. I can tell you only this feature makes the decision totally worth it.
Also, gitlab has way more dev-friendly features than github, which has been recently only copying what gitlab already does.
I do mirror the project to github, in case anyone from there wants to contribute, so I'm not that narrowminded. However, I do prefer gitlab, and it's where I do most of my personal work nowadays.
My brain: GitHub or bust.