As I said in a previous post, I recently had to ditch request. I found about got as a replacement because it was mentioned a couple of times in the request deprecation ticket.
One of the first things I liked about got is that they provide a pretty extensive comparison table between them and alternatives. To be honest, when reading this table I was first drawn to ky, as I’m always interested in limiting dependencies (and dependencies of dependencies) as well as package size. But ky is browser-side only. Damn.
So I had a quick look at got’s migration guide, and it seemed easy enough (plus it had promises, yay). You’ll probably find it’s a great place to start, and maybe it will even be all you need. I still had to dig a bit more for a few things though.
The first one is that, by default, got will throw an exception whenever the return HTTP code isn’t 200. It might sound like a perfectly normal behavior to you, but I was using at least one API that would return a 404 code during normal operations (looking at you, MailChimp), and I certainly didn’t expect that to throw an exception!
The solution to that (apart from rewriting your code to deal with exceptions in cases were you used to deal with return data another way) is to set throwHttpErrors
to false in your request parameters (cf example code at the end of this post).
The second one was to get binary data, but actually in this case I find got much clearer than request: in order to get binary data with request, you need to set encoding
to null in the parameters. With got, you’ll replace that with responseType: "buffer"
.
Some other small things: the typings (@types/got) are better than request’s, at least concerning the request parameters, which means you’ll probably have to cast some fields there (for instance, method
isn’t a string
but a "GET" | "POST" | "PUT" ...
). And the timeout is, as I understood, different in got and request: in request, it’s a timeout before the server starts responding, while in got I believe it’s the timeout before the server finishes responding. Interesting for me as sometimes I use request/got to download files, and I’m interested in dealing with slow download speeds if they happen to occur.
Finally, here are a couple of functions as they were with request and how they became with got:
function requestFile(url: string): Promise<Buffer> { return new Promise((resolve, reject) => { let requestParameters = { method: 'GET', url: url, headers: { 'Content-Type': 'binary/octet-stream' }, // *Note:* if you expect binary data, you should set encoding: null (https://www.npmjs.com/package/request) encoding: null, // todo: find a way to have timeout applied to read and not just connection timeout: 2_000 }; request(requestParameters, (error, response, body) => { if (error) { reject(error); } else { resolve(body); } }); }); } async function requestFile(url: string): Promise<Buffer> { const reqParameters = { method: <'GET'>'GET', headers: { 'Content-Type': 'binary/octet-stream' }, responseType: <'buffer'>'buffer', timeout: 3_000, throwHttpErrors: true }; const response = await got(url, reqParameters); return response.body; } function sendApiRequest( method: 'DELETE' | 'GET' | 'POST', route: string, body?: any, headers?: headersArray): Promise<any> { return new Promise((resolve, reject) => { let requestParameters = { method: method, url: this.API_ROOT + route, body: body ? JSON.stringify(body) : null, headers: <{'API-Authorization': string; [key: string]: string}>{ 'API-Authorization': this.apiKey } }; if (headers) { for (const h of headers) { requestParameters.headers[h.name] = h.value; } } request(requestParameters, (error, response, body) => { if (error) { reject(error); } else { const parsedBody = JSON.parse(body); let res: any; if (parsedBody.data) res = parsedBody.data; else res = parsedBody; resolve(res); } }); }); } async function sendApiRequest( method: 'DELETE' | 'GET' | 'POST', route: string, body?: any, headers?: headersArray ): Promise<any> { const reqUrl = this.API_ROOT + route; let reqParameters = { method: method, headers: <{[key: string]: string; 'API-Authorization': string}>{ 'API-Authorization': this.apiKey }, body: body ? JSON.stringify(body) : undefined, retry: 0, responseType: <'text'>'text', throwHttpErrors: false // seriously what a shitty default }; if (headers) { for (const h of headers) { reqParameters.headers[h.name] = h.value; } } const response = await got(reqUrl, reqParameters); const parsedBody = JSON.parse(response.body); let res: any; if (parsedBody.data) res = parsedBody.data; else res = parsedBody; return res; }
0 Responses
Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.