Open indeedwatson opened 5 years ago
Hi @indeedwatson Can we see your full schema file and appsync config ?
Do you have field inside Query
that returns a Card
? And do you have a mappingTemplate for it too?
@bboure this isn't my own code, I'm porting a project that has been made with the AWS web GUI to sls, so I'm not sure about sharing the whole config, I'm sorry, but I can share snippets that might be relevant:
type Query {
getAllCardGroups: [CardGroup]
getAllCardLists: [CardList]
getCard(cardId: ID!): Card
getCardAnswer(id: ID!): CardAnswer
getCardGroup(groupId: ID!): CardGroup
}
And card-group-request.vtl
#**
The value of 'payload' after the template has been evaluated
will be passed as the event to AWS Lambda.
*#
{
"version" : "2017-02-28",
"operation": "Invoke",
"payload": {
"field": "cardGroup",
"arguments": $utils.toJson($context.arguments),
"source": $utils.toJson($context.source)
}
}
The response template is just one line: $util.toJson($context.result)
Might be just copy-paste error, but in your group field resolver you have
request: "card-group-request.v
response: "common-response.vtl
Both start with "
(with no "
in the end). Also your card-group-request.v should probably be .vtl?
Might be just copy-paste error, but in your group field resolver you have
request: "card-group-request.v response: "common-response.vtl
Both start with
"
(with no"
in the end). Also your card-group-request.v should probably be .vtl?
Sorry, that's indeed copy paste error. I haven't been able to solve this, since I can't see what I'm doing differently than what's being shown in the documentation.
I've found that occasionally CloudFormation/AppSync doesn't update the templates even though the CloudFormation JSON looks to be correct. For example, this Pipeline behavior I posted about in the AWS forums. I have also experienced the resolvers not attaching correctly as you show in your example. I suspect this is a bug in CloudFormation since the template does get copied up into the console correctly but the AppSync API doesn't seem to get updated.
When this happens, after banging my head on the desk for a little while, I find that changing the name of the appSync API will cause CloudFormation to recreate everything and the templates will be attached and updated properly.
I've had the same issue. After making changes to the schema, stack template, and resolvers, one of the endpoints would not attach to the resolver. All of the files were correctly uploaded to S3 and the schema and template were correct. The only way to fix the issue was to delete the stack and recreate it, which certainly will not be a viable solution in production.
@mentoc3000 - I've still not been able to reliably reproduce the problem. My working theory is that some sort of parsing error occurs when deploying the GraphQL Schema (due to a legitimately bad schema) and that puts AppSync into a bad state (but invisible to mere mortals) that cannot be updated any further. So even after fixing the problem AppSync won't accept further updates.
I still want to work more on reproducing it, maybe I can find the time soon...
Related issue on the AppSync Github - https://github.com/aws/aws-appsync-community/issues/146
Same here, losing significant time to this. Our CI pipeline deploys a throwaway stack each time so is generally OK, but if you repeatedly deploy to the same stack during development and somehow put it into a bad state, your resolvers go missing silently and tons of stuff falls over.
When I look at the cloudformation files I can see the missing resolvers are still defined and look OK :(
As a workaround, I've started printing a build timestamp into a comment on the first line of all mapping files (there may be a better way, but I was inspired by https://forum.serverless.com/t/is-there-a-way-to-insert-a-timestamp-into-a-lambda-environment-variable/13036/2)
This way, each time the stack is deployed all the resolvers are new, and (hopefully) should re-attach...
I just reported a couple of issues that I think might be caused by the same root issue: https://github.com/sid88in/serverless-appsync-plugin/issues/393 https://github.com/sid88in/serverless-appsync-plugin/issues/394
To reproduce, change the data source's type as suggested in the issues above. This is causing a ton of headaches for us.
UPDATE: After looking through this and the source code for this plugin, I'm pretty sure that the problem is outside the plugin's control. Based on this comment (https://github.com/aws/aws-appsync-community/issues/146#issuecomment-765616945) the detaching is "by design" and is controlled by AWS themselves. There "might be" a way for the plugin to mitigate the issue, but I doubt it.
Related issue on the AppSync Github - aws/aws-appsync-community#146
Somewhat inspired by @Dave-McCraw 's comment above I have also added a workaround in our CDK code which computes an md5 checksum of the Schema and includes this as a comment in the resolver templates, as our CD will run cloudformation step if the clouformation has changed (as such a timestamp would run this every time and slow our deploys when in reality we don't change the schema that often).
I can't share the PR at the moment but here's the implementation if its useful...
appsync.Schema
(which we were doing anyway to use in the new appsync.GraphqlApi()
call) const gqlSchema = appsync.Schema.fromAsset(
join(__dirname, "../shared/graphql/schema.graphql")
);
Produce an md5 checksum of the Schema content (given import crypto from "crypto";
)...
const gqlSchemaChecksum = crypto
.createHash("md5")
.update(gqlSchema.definition, "utf8")
.digest("hex");
Re-usable function to wrap mapping templates to add the comment containing the checksum...
// workaround for resolvers sometimes getting disconnected
// see https://github.com/aws/aws-appsync-community/issues/146
const resolverBugWorkaround = (mappingTemplate: appsync.MappingTemplate) =>
appsync.MappingTemplate.fromString(
`## schema checksum : ${gqlSchemaChecksum}\n${mappingTemplate.renderTemplate()}`
);
Use the re-usable function on either the request or response mapping for each of your resolvers, for example...
blahDataSource.createResolver({
typeName: "Query",
fieldName: "listBlah",
responseMappingTemplate: resolverBugWorkaround(
appsync.MappingTemplate.lambdaResult()
),
});
... I only implemented last night, but seems to be working so far (it certainly reconnected all the resolvers when I deployed it to test environment).
Here's the relevant part of my
serverless.yml
And
schema.graphql
However, when looking at the console:
Nothing gets attached.