Skip to content
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

Merged
merged 7 commits into from Jun 20, 2022

Conversation

sam-goodwin
Copy link
Collaborator

@sam-goodwin sam-goodwin commented Jun 18, 2022

Fixes #137
Fixes #65

export const getDeletionStatus = new AppsyncResolver<
  { executionArn: string },
  string | undefined
>(stack, "getDeletionStatus", {
  api,
  typeName: "Query",
  fieldName: "getDeletionStatus",
  resolve: ($context) => {
    const executionStatus = deleteWorkflow.describeExecution(
      $context.arguments.executionArn
    );

    return executionStatus.status;
  },
});

BREAKING CHANGE: AppsyncResolver is now a Construct and creates the resolvers within its constructor

…removed. Templates are eagerly evaluated so that order can be arbitrary.
@sam-goodwin sam-goodwin self-assigned this Jun 18, 2022
@sam-goodwin sam-goodwin requested a review from thantos June 18, 2022 08:53
@netlify
Copy link

netlify bot commented Jun 18, 2022

Deploy Preview for effortless-malabi-1c3e77 ready!

Name Link
🔨 Latest commit e4d7105
🔍 Latest deploy log https://app.netlify.com/sites/effortless-malabi-1c3e77/deploys/62b0fc76ac61c000090abd56
😎 Deploy Preview https://deploy-preview-275--effortless-malabi-1c3e77.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

src/appsync.ts Outdated Show resolved Hide resolved
src/compile.ts Outdated Show resolved Hide resolved
src/compile.ts Outdated Show resolved Hide resolved
src/compile.ts Outdated Show resolved Hide resolved
src/compile.ts Outdated Show resolved Hide resolved
src/util.ts Show resolved Hide resolved
test-app/src/message-board.ts Outdated Show resolved Hide resolved
src/appsync.ts Outdated Show resolved Hide resolved
test-app/src/message-board.ts Outdated Show resolved Hide resolved
@sam-goodwin sam-goodwin marked this pull request as ready for review June 19, 2022 22:59
@sam-goodwin sam-goodwin requested a review from thantos June 19, 2022 23:01
src/appsync.ts Outdated Show resolved Hide resolved
src/appsync.ts Outdated
* @functionless AppsyncFunction
*/
export class AppsyncResolver<
Arguments extends ResolverArguments,
Result,
Source = undefined
> {
> extends Construct {
Copy link
Collaborator

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?

Copy link
Collaborator Author

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.

Copy link
Collaborator

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.

Copy link
Collaborator Author

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", {
Copy link
Collaborator

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?

Copy link
Collaborator Author

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.

Copy link
Collaborator

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
Comment on lines 355 to 357
if (resolverCount === 0) {
if (pipelineConfig.length !== 0) {
throw new Error(
Copy link
Collaborator

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?

Copy link
Collaborator Author

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.

Copy link
Collaborator Author

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
Comment on lines 557 to 559
throw new Error(
`invalid Expression in-lined with Service Call: ${expr.kind}`
);
Copy link
Collaborator

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?

Copy link
Collaborator Author

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

Copy link
Collaborator

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

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in the async change.

Comment on lines +330 to +333
constructor(
options: AppsyncFieldOptions,
resolve: ResolverFunction<Arguments, Result, Source>
) {
Copy link
Collaborator

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...

aws/aws-cdk#18351 (comment)

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?

Copy link
Collaborator Author

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?

Copy link
Collaborator

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!"]
});

Copy link
Collaborator Author

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?

Comment on lines -752 to +753
\\"version\\": \\"2018-05-29\\",
\\"payload\\": null
\\"version\\": \\"2018-05-29\\",
\\"payload\\": null
Copy link
Collaborator

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?

Copy link
Collaborator Author

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

Copy link
Collaborator

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.

Comment on lines +14 to +24
new AppsyncResolver(
stack,
"getPost",
{
api,
typeName: "Query",
fieldName: "getPost",
},
// valid - inline arrow function
() => null
);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love these tests.

They do get stuck periodically though

image

Copy link
Collaborator Author

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.

Copy link
Collaborator

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?

@sam-goodwin sam-goodwin merged commit e1dcd83 into main Jun 20, 2022
@sam-goodwin sam-goodwin deleted the appsync-remove-add-resolver branch June 20, 2022 23:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
2 participants