-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
migrate away from request #4655
Comments
I believe it was in one of the private channels on Discord, will try to dig it up. IIRC we didn't go into much detail, just that it'd need to be replaced and that we'd have to keep in mind Self-hosting Shields server users which currently benefit from requests ability to auto-detect and honor the standard proxy env vars (something I believe is missing from most request alternatives |
This is related to #3368, but yea, I remember @calebcartwright mentioning the limitations in proxy support in other HTTP clients. That was a while ago. I wonder if there is a solution for any of those now. Should we merge these two issues? |
Yeah sorry. They are probably the same thing. |
It seems like we should open a new issue which combines the scope of both. Request being unmaintained is making this more urgent than it was before, and deserves high billing, although the first order of business is probably to test the effectiveness of that memory cache. |
We talked a bit the other day about some of the mechanics of this (e.g: an adaptor layer that allows our service code to use request-style params with another library), but it seems like a very major decision we need to make is which library we're going to migrate to. While its on my mind, I'll post this link to discussion of possible alternatives as a starting point, but in making this choice we also need to try and work out what our requirements even are (what is the current subset of the request feature set we depend on?) |
In my experience, the main differentiator with Proxy support is an important requirement for self-hosting Shields, though admittedly not relevant for the Shields.io service. FWIW at this point I expect most (if not all) of the alternative prominent client libs will have the core features we'd need, and I'm guessing it will likely boil down to ergonomics and ease of request-replacement in our codebase |
We talked about this again in the ops meeting today. Just re-reading the thread, basically the deal is: request configures proxying based on the So it sounds like the options if we move to another library are:
*lets abstract the fact we don't have a good method for doing this at the moment and assume it is covered under #5866 @calebcartwright do you have any input on either of those options? If you can flesh either of those things out a bit, great - that would help. If not, even confirming that is useful. We will at least know what the next things we need to research are.. |
I've become pretty partial to The only thing I feel strongly about is that we need to maintain the ability for self-hosted instances to work with proxies/network restricted environments; otherwise a core use case for self-hosted is largely defeated. I don't recall specifics offhand, but there's cases of libs (and/or their internal deps which support proxies) utilize env vars for configuration, just not the standard ones (e.g. it won't pick up If we end up using a replacement that doesn't have any auto detection, then yes I'd think either adding some new configuration options we support and/or auto mapping from the standard vars would be a viable option. I'd suggest we select the request replacement based on what will work best for Shields, provided said replacement can be configured to support proxies, and then just take the work on the proxy piece forward based on the contexts and constraints of that replacement we're targetting |
For example, https://github.com/gajus/global-agent#environment-variables Or with one minor additional env var, be configured to pick up the standard vars: |
Good shout on global-agent. That sounds like it would resolve the one outstanding issue |
OK then. I've spent a bit of time thinking about this and playing with things. Aside from request and got I think there are really 3 other libs in the Node JS ecosystem worth looking at: axios, node-fetch and superagent. Obviously one of the things we want to optimise for is performance, but it isn't the only thing that is important (if it was, we'd just stick with request forever). We also want a project which is actively maintained and some kind of reasonable expectation that this thing is still going to be around in the future. As we're in the process of doing this it is clear that changing our HTTP client is a big job. If we pick something that is memory efficient but then we end up going through this same process a year or two down the line that is counter-productive. I did a bit of testing making some calls with various HTTP clients and In terms of picking, there are a few considerations:
const superagent = require('superagent')
const data = await superagent.get('https://google.co.uk')
const body = data.text const fetch = require('node-fetch');
const data = await fetch('https://google.co.uk')
const body = await data.text() // note we have to await this I suspect this doesn't really help us much performance-wise because in 99% of cases we need to evaluate the body so it actually probably means we just have to make more code changes to try it. This might allow us to squeeze a tiny bit of extra performance when we are serving an error response (because we only care about the status code, I think) but we might need to make some changes to unlock that. I think I am leaning slightly more towards trying #6160 again with node-fetch but if anyone else has any points to add, please do.. I'll probably give it a few days before diving into this again. |
Will be the one to ask the dreaded question.. any difference between those two in terms of proxy support? 😆 Would it even potentially be worthwhile to consider using the stdlib modules directly? I know they aren't exactly known for ease of use and great ergonomics, but I feel like the codebase is structured well in terms of sufficient encapsulation that I wouldn't rule out the stdlib out of pocket, especially given the performance emphasis. Between superagent and node-fetch specifically, think I'd agree with you on node-fetch being the better candidate for a next test. |
When it comes to proxying, it is the same story for node-fetch and superagent really, which is in turn pretty much the same story as got.
I think probably not. I've not really evaluated this option but if we go down that route, we're going to end up writing some kind of abstraction (however thin) over the node core HTTP libs, at which point we're essentially making our own version of got/superagent/node-fetch (admittedly focussing on only a small subset of the features) only it will be worse and maintained by us. I think when it comes to this kind of low-level abstraction there is a huge benefit in using something off-the-shelf instead of home-brewing our own solution. (See ScoutCamp for more details). Sure we are trying to serve a lot of traffic on modest infrastructure but I don't think we are enough of a special unique unicorn that we need to write our own HTTP abstraction for it and I don't really think we'd make a better job of it than any of the big popular projects. |
👍 Happy to test this again, just lmk
Fair enough. I'm not actively pushing for it, and am very much hoping that From the sound of it though, I'm probably a bit more open to that possibility. However, we're fully aligned on the plan to go after |
Not looked at this in a while, but it is still on my mind. @paulmelnikow suggested looking at https://github.com/nodejs/undici - it is an interesting option and it is possible the the fetch implementation that eventually lands in core my end up looking like https://github.com/Ethan-Arrowood/undici-fetch (backed by https://github.com/nodejs/undici ). There's a few mins on this at the end of https://www.youtube.com/watch?v=fcj2Z9dL060 The thing with undici (having done a small amount of reading) is that it doesn't use node's (current) HTTP stack internally at all - its a completely from-the-ground-up implementation. This means that nock doesn't work with it and neither will global-agent (nor any other packages that rely on your http client being an abstraction over Node's HTTP internals). Given it doesn't (yet) have support for mocking nodejs/undici#531 that's a blocker for us at the moment plus we'd have to roll our own proxy configuration. I think that is still leaning me towards node-fetch at the moment (again viewing it as a possible 'stepping stone' to a native fetch implementation) but it is worth keeping one eye on undici as it develops.. |
Coming from undici by following the ping. We are about to release undici@4 within a or two which does support mocking. |
I've been having a slightly more detailed think about node-fetch and the featureset we need from it. In terms of the options of request/got we are currently using:
So all that is do-able (although some of those cases need a bit of work) but here's the thing it doesn't have:
There are currently only two services using this - coverity and jenkins - but it is a non-zero number. I think the first thing to do on this is research/test the node-fetch/custom agent setting |
Been dragging this on for a bit, but having tried out both got and node-fetch for a bit with a production workload and evaluated both the performance and library ergonomics the conclusion is to go with got. Once #7175 is merged, I will continue to pick through the remaining instances of request replacing with got. |
Keeping track of the instances in #4655 (comment) and crossing them off as I do them. 2 more to go. As I'm working on this I realise there are quite a few more tasks. This is mainly for my own reference:
|
I suspect we are a long way from this feature reaching stability in a LTS node version, but first commit adding experimental undici-based global |
📋 Description
Request is no longer maintained:
https://github.com/request/request#deprecated
We need to switch to a different library. This is going to be an absolutely monstrous job.
@calebcartwright you mentioned in #4644 that there has been some discussion around this already. I couldn't find an issue anywhere. Do you have any kind of summary of where we've got to on this. I'm aware its somewhat complex as our use of the library is quite involved, there are many other libraries we could potentially migrate to, and none are an obvious like-for-like replacement for request.
The text was updated successfully, but these errors were encountered: