-
Notifications
You must be signed in to change notification settings - Fork 4
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
feat: request module #53
base: main
Are you sure you want to change the base?
Conversation
instance = createH(registryInstance); | ||
}); | ||
test('based', async () => { | ||
nock('http://yolo').get('/foo').reply(200, 'ok'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm worried that we are generating dependencies in different packages. Can we reuse packages that are already in use in the lib?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't want to use this library?
}, | ||
) => { | ||
results.map((result) => { | ||
// @ts-ignore |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we use any
instead?
let response!: Response; | ||
logger.log('Start request', config); | ||
// eslint-disable-next-line prefer-const | ||
response = await next(config); | ||
logger.log('End request', config); | ||
return response; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let response!: Response; | |
logger.log('Start request', config); | |
// eslint-disable-next-line prefer-const | |
response = await next(config); | |
logger.log('End request', config); | |
return response; | |
logger.log('Start request', config); | |
const response = await next(config); | |
logger.log('End request', config); | |
return response; |
return { | ||
result: error ? 'error' : 'success', | ||
status: error ? status : response.status, | ||
url: url.toString(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we cannot store the entire url in the label:
- with a large number of unique urls the prom database will get huge
- the url may contain API keys
I think it's better to store only a domain name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok! I will fix it
timer(serialize(config, response)); | ||
} catch (error) { | ||
if (!(error instanceof Error)) { | ||
timer(serialize(config, response)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you are not passing an error in args it will have success status in the metrics
in defaultSerializer:
result: error ? 'error' : 'success'
if (obj instanceof Object) { | ||
return Object.keys(obj).reduce((newObj, key) => { | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pls, don't use @ts-ignore
@@ -0,0 +1,26 @@ | |||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | |||
export const deepClone = (obj: any) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's better to move this to packages/utils
} | ||
|
||
if (obj instanceof Array) { | ||
return obj.reduce((arr, item, i) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why reduce
and not map
? did you copy deepClone
from some package?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps we should take the cloneDeep from lodash?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I do. I took it only for prototyping.
return (requestConfig: RequestConfig) => { | ||
// copy object bcs we can mutate it | ||
const internalConfig = deepClone(requestConfig) as InternalConfig; | ||
internalConfig.attempt = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess that in service with a middleware design we should not have this configuration on a global level, but have it in the configs of the specific middleware responsible for repeating queries
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean? Can I pass this variable to the context
scope?
const fetchCall = ({ url, baseUrl, ...rest }: RequestConfig) => | ||
fetch(getUrl(baseUrl, url), rest); | ||
|
||
export function compose(middleware: Middleware[]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this module is written in more of a functional style and not very similar to the architecture of nestjs modules. It would be great if we could keep to one code style
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think a better way to create this module without some framework abstraction and wrote Nestjs binding. Because we don't need to use Nestjs abstraction inside this module. This way provides more clear code and it is a very popular way described in Uncle Bob's book.
And I think we should use this way in other modules in this repo. For example, middleware service looks very difficult but if we remove Nestjs abstraction from middleware code all ideas of that plugin will be looks like one line of code.
const response = await next(config); | ||
if (!baseUrls.length) return response; | ||
if (isNaN(config.attempt) || config.attempt <= 0) return response; | ||
config.baseUrl = pickUrl(baseUrls, config.attempt); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's good that we're mutating the config
object here. If a mutation is required, I would prefer to have a context
arg here, which contains the config
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay! I will change the config and rewrite this case and all the same cases
Middlewares - is the main difference between the request module and the fetch module
You can add global middlewares into the Module instance. These middlewares will be used for each request.
For example, this standard middlewares will be repeated on each network error 5 times and change the base URL on each failure.
Let's set up our module
And use it