Created
October 19, 2022 08:00
-
-
Save dmozgovoi/af1ab4ebba72bb0228df04498b23c490 to your computer and use it in GitHub Desktop.
HttpClient variation with flexible output format parsing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as http from 'http'; | |
import * as https from 'https'; | |
import got, { Got, ExtendOptions, Headers, CancelableRequest, Response } from 'got'; | |
import CacheableLookup from 'cacheable-lookup'; | |
import { decodeData, TypeOf, TSchema } from '../decoder'; | |
export const DefaultHttpClientOptions = { | |
keepAlive: true, | |
maxSockets: 10, | |
// rough guess: 10 open sockets for each agent is enough, keeping more | |
// than a ten can become dangerous when http client amount increase | |
}; | |
export const gotDefaultOptions = { | |
urlPrefix: '', | |
dnsCache: new CacheableLookup({ | |
maxTtl: 60 * 30, // 30 minutes | |
}), | |
context: { someContext: 'here' }, | |
handlers: [ | |
(options: any, next: Function) => { | |
Error.captureStackTrace(options.context); | |
return next(options); | |
}, | |
], | |
hooks: { | |
beforeError: [ | |
(error: any) => { | |
error.source = error.options.context.stack.split('\n'); | |
return error; | |
}, | |
], | |
}, | |
agent: { | |
http: new http.Agent(DefaultHttpClientOptions), | |
https: new https.Agent(DefaultHttpClientOptions), | |
}, | |
}; | |
type GetOptions = { | |
headers?: Headers; | |
}; | |
type PostOptions = { | |
headers?: Headers; | |
body?: string | Buffer | undefined; | |
json?: object; | |
}; | |
/** | |
* Class-wrapper for HttpClient (now it's got) responses and checking it`s schema | |
* In case you need to implement new data serialization format, add methods for it`s processing here | |
*/ | |
class HttpResponseWrapper { | |
private _gotResponse: CancelableRequest<Response<string>>; | |
constructor(gotResponse: CancelableRequest<Response<string>>) { | |
this._gotResponse = gotResponse; | |
} | |
async json<S extends TSchema>(schema?: S): Promise<TypeOf<S>> { | |
const data = await this._gotResponse.json(); | |
if (!schema) { | |
return data; | |
} | |
return decodeData<S>(schema, data, 'httpClient'); | |
} | |
} | |
export class HttpClient { | |
got: Got; | |
constructor(options: Got | ExtendOptions) { | |
this.got = got.extend({ | |
...gotDefaultOptions, | |
...options, | |
}); | |
} | |
get(path: string, options?: GetOptions): HttpResponseWrapper { | |
return new HttpResponseWrapper(this.got.get(path, options)); | |
} | |
post(path: string, options?: PostOptions): HttpResponseWrapper { | |
return new HttpResponseWrapper(this.got.post(path, options)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment