De-duplicate parallel reading operations using beforeRequest hook: how to store Response promise? #672
Unanswered
kleinfreund
asked this question in
Q&A
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
(This is just a small side quest to satiate my curiosity and not a critical issue I need to solve or a problem with ky. I'm basically just looking for ideas.)
I'm working on an application that triggers a fairly large number of requests to REST APIs returning data in JSON format used to populate things in the UI.
In some cases, I "over-fetch" data because I'd otherwise have a cumbersome data flow between otherwise independent trees of UI components. A good example is a user's profile: for its data, we
GET /users/:userId
. However, in the header, we also show a user menu with their avatar (much like GitHub does). This data is also populated retrieved usingGET /users/:userId
.Custom approach wrapped around ky
I realized that for reading operations like this, the network requests could be de-duplicated. For any subsequent identical (i.e. has the same reading (GET or HEAD) HTTP method and the same URL) reading operation, I avoid the network request and instead use the
Promise<KyResponse>
returned by ky. That promise was previously stored in aMap<string, Promise<KyResponse>
where the keys are HTTP method plus:
plus request path.Simplified version of my code
One caveat with this approach is that I have to
response.clone()
before reading the response body for all requests as I'd otherwise try to consume the same stream multiple times.A real issue with this approach is that I compute the map key using request paths and not fully resolved URLs. That's a potential bug as I might miss request parameters from an
RequestInit
object which should make the operation not identical. And of course I couldn't use this if multiple origins were to be serviced by this code. I can't get the full URL ky will use before aoptions.beforeRequest
hook without trying to implement the same URL resolution strategy as ky does (I know usingoptions.prefixUrl
is just string concatenation, but with a potential move tooptions.baseUrl
, this might change). But I could still ensure the map keys make use ofoptions.prefixUrl
and any query parameters to address these issues.ky-centered approach using a
Response
-returningoptions.beforeRequest
hookI know that ky
options.beforeRequest
hooks can returnPromise<Response>
to avoid network requests. At first I wanted to use this in my implementation, but I couldn't figure out how to populate the map of reading operations with aPromise<Response>
to begin with. I can populate it with aResponse
using aoptions.afterResponse
hook, but that's of course too late. Parallel requests will have already been triggered before I get to this point.I would need something like a
options.beforeResponse
hook (tricky naming problem) to get thePromise<Response>
before it settles, but that doesn't exist and I'm not sure it's valuable for ky to even have something like this in the first place.That being said, performing this task using a
options.beforeRequest
hook would address the issue I outlined above: access to the fully resolved URL ky will use which will be available on theRequest
object passed to the hook. That would be a significant advantage.So, all this being said (was this a blog post?): can anyone think of a way to de-duplicate parallel reading operations as described above using ky and its
options.beforeRequest
hooks?Beta Was this translation helpful? Give feedback.
All reactions