-
Notifications
You must be signed in to change notification settings - Fork 134
feat(response-cache): add extras property to get scope and its metadata from buildResponseCacheKey #2202
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
base: main
Are you sure you want to change the base?
feat(response-cache): add extras property to get scope and its metadata from buildResponseCacheKey #2202
Conversation
🦋 Changeset detectedLatest commit: 9e8ea70 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
4f30aba to
a5468bb
Compare
a5468bb to
9e8ea70
Compare
…ta from buildResponseCacheKey
9e8ea70 to
c4de9af
Compare
|
Hi @ardatan, I'm back with a new proposal for this scope functionality with some improvements. |
|
@EmrysMyrddin Could you take a look? |
| new Proxy( | ||
| { | ||
| documentString: getDocumentString(onExecuteParams.args), | ||
| variableValues: onExecuteParams.args.variableValues, | ||
| operationName: onExecuteParams.args.operationName, | ||
| sessionId, | ||
| context: onExecuteParams.args.contextValue, | ||
| extras: undefined as any, | ||
| }, | ||
| { | ||
| get: (obj, prop) => { | ||
| if (prop === 'extras') { | ||
| return getScopeFromQuery(schema, onExecuteParams.args.document.loc.source.body); | ||
| } | ||
| return obj[prop as keyof typeof obj]; | ||
| }, | ||
| }, | ||
| ), |
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 remembre how it was implemented before, but is there a reason to use a proxy instead of classic getters?
Like this:
| new Proxy( | |
| { | |
| documentString: getDocumentString(onExecuteParams.args), | |
| variableValues: onExecuteParams.args.variableValues, | |
| operationName: onExecuteParams.args.operationName, | |
| sessionId, | |
| context: onExecuteParams.args.contextValue, | |
| extras: undefined as any, | |
| }, | |
| { | |
| get: (obj, prop) => { | |
| if (prop === 'extras') { | |
| return getScopeFromQuery(schema, onExecuteParams.args.document.loc.source.body); | |
| } | |
| return obj[prop as keyof typeof obj]; | |
| }, | |
| }, | |
| ), | |
| { | |
| documentString: getDocumentString(onExecuteParams.args), | |
| variableValues: onExecuteParams.args.variableValues, | |
| operationName: onExecuteParams.args.operationName, | |
| sessionId, | |
| context: onExecuteParams.args.contextValue, | |
| get extras() { | |
| return getScopeFromQuery(schema, onExecuteParams.args.document.loc.source.body); | |
| }, | |
| }, |
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.
A recent habit to use proxies for their flexibility, but I can see that a getter in this case would fit better for clarity sake.
| return { scope: 'PUBLIC' as const, metadata: {} }; | ||
| }); | ||
|
|
||
| return fn({ query }); |
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.
This will disallow memoization isn't it ? Since { query } creates a new object each time the function is called.
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.
And I'm not sure to understand why schema is not part of the memoize1 key ? Because I fear that on schema update, you will get outadated metadata for the same query.
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.
Fair points!
I'll include schema using memoize2 function and stringify those objects to fix comparison.
| export let schema: GraphQLSchema; | ||
| let ttlPerSchemaCoordinate: Record<string, CacheControlDirective['maxAge']> = {}; | ||
| let scopePerSchemaCoordinate: Record<string, CacheControlDirective['scope']> = {}; |
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 do you extract those outside of the plugin? I feel that it will break things, because multiple instances of the same plugin would share those variables.
| export function isPrivate( | ||
| typeName: string, | ||
| data?: Record<string, NonNullable<CacheControlDirective['scope']>>, | ||
| ): boolean { | ||
| if (scopePerSchemaCoordinate[typeName] === 'PRIVATE') { | ||
| return true; | ||
| } | ||
| return data | ||
| ? Object.keys(data).some( | ||
| fieldName => scopePerSchemaCoordinate[`${typeName}.${fieldName}`] === 'PRIVATE', | ||
| ) | ||
| : false; | ||
| } |
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 do you have to make a duplicate of this function outside of the plugin?
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.
Mb I merged local code I made last year with the one I use today and simply forgot there was already this function.
I'll keep the exported one since it's needed in get-scope.ts file.
… better scope memoization
|
Hi @EmrysMyrddin, how's it going today ? I made updates to fix the points you brought up :
|
Issue related : #2181
Description
Include a new
extrasproperty to getscope(as aProxyto avoid performance impact when unused) inbuildResponseCacheKey, allowing more granularity over cache control.Type of change
How Has This Been Tested?
I added some unit tests to check that
PRIVATEscope is correctly retrieved from a query, when directive@cacheControl(scope: PRIVATE)is put on query, field and subfield.Checklist:
CONTRIBUTING doc and the
style guidelines of this project