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(appsync): remove addResolver from AppsyncResolver and lazy template evaluation #275
Conversation
…removed. Templates are eagerly evaluated so that order can be arbitrary.
✅ Deploy Preview for effortless-malabi-1c3e77 ready!
To edit notification comments on pull requests, go to your Netlify site settings. |
src/appsync.ts
Outdated
* @functionless AppsyncFunction | ||
*/ | ||
export class AppsyncResolver< | ||
Arguments extends ResolverArguments, | ||
Result, | ||
Source = undefined | ||
> { | ||
> extends Construct { |
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.
Didn't we just make the StepFunction not a Construct/Resource? Maybe AppSync should wrap and not be too? What is the value of it itself being a construct? Will we ever want to call an app sync resolver from lambda?
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.
Not sure we would ever call a resolver directly. I don't think it's even possible? We can execute graphql queries but not individual resolvers.
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 if there is value in this being a construct, it is fine.
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 also fine with moving it to resource
. Keep things consistent.
src/appsync.ts
Outdated
|
||
this.resolvers = memoize(() => synthResolvers(props.api, this.decl)); | ||
|
||
this.resource = new aws_appsync.CfnResolver(this, "Resource", { |
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 CfnResolver and not he L2?
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.
Because the L2 doesn't expose IResolvable which I need to support lazy evaluation. Without lazy evaluation, users are forced to order things eagerly.
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.
Makes sense, I think we'll need to do this in other places.
src/appsync.ts
Outdated
if (resolverCount === 0) { | ||
if (pipelineConfig.length !== 0) { | ||
throw new Error( |
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.
In my PR I removed this check. I am not sure I understand the purpose, do we think we'll mess up? Couldn't an integration provide only vtl in the future?
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.
Yeah, I don't really know what this is checking for either. Seems to check for a situation where we rendered a pipeline without ever calling a resolver? Seems like internal bug.
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.
Which PR should we merge first?
src/appsync.ts
Outdated
throw new Error( | ||
`invalid Expression in-lined with Service Call: ${expr.kind}` | ||
); |
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.
Synth error, also I don't understand how this happens?
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 haven't changed this code. It is a bit hacky - it is trying to support various different ways in which the result of an Integration call may be referenced.
E.g.
call().result
call().result[0]
This will be fixed with your a-normal form change? #280
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.
Ohh, yeah, I actually removed this whole function, lol
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.
in the async change.
constructor( | ||
options: AppsyncFieldOptions, | ||
resolve: ResolverFunction<Arguments, Result, Source> | ||
) { |
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 was trying to remember why field and resolver are different.
Ha...
I don't like how buggy it is, ran into this again when working on the authorizer example.
Can you add a validator or something that checks to see if a resolver was actually created?
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.
Do you mean a node validator? There is no Construct
here for me to add that validator to. Also, if the resolver isn't added, then the validator also wouldn't be added? Is this solved with just tests?
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.
Hmm, you could put it on the api.
api.node.addValidator(() => {
api.node.tryFindChild(`${props.typeName}${props.fieldName}Resolver`) ? [] : ["uhh ohh no resolver!"]
});
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 have a typeName
or fieldName
at this point. That happens later when you call addQuery
. I don't think there's anything to validate here?
\\"version\\": \\"2018-05-29\\", | ||
\\"payload\\": null | ||
\\"version\\": \\"2018-05-29\\", | ||
\\"payload\\": null |
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 meant to do this?
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 recall changing the vtl logic
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 was a literal string change.
new AppsyncResolver( | ||
stack, | ||
"getPost", | ||
{ | ||
api, | ||
typeName: "Query", | ||
fieldName: "getPost", | ||
}, | ||
// valid - inline arrow function | ||
() => null | ||
); |
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.
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.
Hmm that's odd, any idea why that would be? I've never seen that happen.
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 am not sure, never get an error, just spins. Running it on its own works fine, maybe a race condition?
Fixes #137
Fixes #65
addField
to its own class and also apply lazy evaluationBREAKING CHANGE: AppsyncResolver is now a Construct and creates the resolvers within its constructor