Closed kolpav closed 6 years ago
You definitely need a cacheKeyFn if you're using an object as a key where you want to treat that object as a value rather than a reference. I like the one you made that considers keys being defined in a different order as equivalent, very good.
@leebyron if we do like this, how can we make use of, say where in
of mysql (knex)?
@kolpav Is this still the best way to do this? Is there a better (official) way to pass GraphQL args down to dataloader functions?
@timscott You need to be able to turn your args to value which can be used as an object key (string
or symbol
). In my case I am turning object into string while ignoring order of keys because {id: '1', orderBy: 'new'}
produces same query as {orderBy: 'new', id: '1'}
so I consider them equivalent. It was written for my specific use case and it worked fine your needs might differ so I don't think there should be official cacheFn
.
@kolpav Yeah, I ended up adding the args to the key and doing just JSON.stringify(key)
. The code sample in your OP does a shallow stringify, which might miss differences in deep objects like InputTypes.
That's a great point about orderBy
and other args that might not affect the actual content. I guess those have to me pulled out by name, which seems might not scale well. Perhaps InputTypes or Interfaces could help matters.
@timscott
I don't think you should use JSON.stringify(key)
because it does not guarantee key order it could produce some really hard to catch bugs.
The code sample in your OP does a shallow stringify, which might miss differences in deep objects like InputTypes.
Entire object is stringified just top levels keys are ordered but I guess thats what you meant. You could write recursive version of my objectCacheKeyFn
but I would think twice before caching resolvers with such complicated arguments that you need nested objects. Are you sure there is a chance of calling same resolver with same arguments more than once during lifetime of a single request?
@kolpav Ah, good point. Maybe something like this covers every scenario: https://github.com/puleos/object-hash
@kolpav Ah, good point. Maybe something like this covers every scenario: https://github.com/puleos/object-hash
@kolpav Ah, good point. Maybe something like this covers every scenario: https://github.com/puleos/object-hash
Hello,
First of all thank you for this cool library my db server is no longer on fire 😄
Before I jump to my question I would like to explain in detail problem I am trying to solve. Maybe I am doing it wrong alltogether but you can skip to question at the end if you like.
Explanation
I am using relay style pagination it could be described by these interfaces
And I have a query which returns
posts
based oncount
,after
,orderBy
like so:Everything works perfectly but if you want to resolve value for
hasNextPage
fromIPageInfo
you need to make same request to db as you would foredges
but withcount + 1
and see ifhasNextPage = results.length > count
. Hope that makes sense.I didn't liked that very much. We are making quite expensive query just to know if there are any more results. I solved this by using
postModel.getPosts.load({ after, orderBy, count: count + 1 })
foredges
and just droping last result if there were more thancount
. Now I can make same request as I made foredges
forhasNextPage
it looks completelly samepostModel.getPosts.load({ after, orderBy, count: count + 1 })
so I get cached version, bypassing call to db alltogether! But I need to use this uglycacheKeyFn
This question can be applied to any call to
load
where its argument is an object and not just simpleid
. Is this wrong?Question
I basically need this: