sid88in / serverless-appsync-plugin

serverless plugin for appsync
MIT License
951 stars 189 forks source link

Resolvers not getting attached #225

Open indeedwatson opened 5 years ago

indeedwatson commented 5 years ago

Here's the relevant part of my serverless.yml

mappingTemplates:
  - dataSource: WordListResolver
    type: Card
    field: group
    request: "card-group-request.v
    response: "common-response.vtl
  - dataSource: WordListResolver
    type: Card
    field: list
    request: card-list-request.vtl
    response: common-response.vtl

And schema.graphql

schema {
  query: Query
  mutation: Mutation
  subscription: Subscription
}

type Card {
  group: CardGroup!
  id: ID!
  list: CardList!
  phrase: String!
  sentences: [DefinitionSentence]
  translation: String!
}

However, when looking at the console:

image

Nothing gets attached.

bboure commented 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?

indeedwatson commented 5 years ago

@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)

artoliukkonen commented 5 years ago

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?

indeedwatson commented 5 years ago

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.

cameroncf commented 5 years ago

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.

mentoc3000 commented 5 years ago

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.

cameroncf commented 5 years ago

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

alextriaca commented 3 years ago

Related issue on the AppSync Github - https://github.com/aws/aws-appsync-community/issues/146

Dave-McCraw commented 3 years ago

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 :(

Dave-McCraw commented 3 years ago

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

nthornton2010 commented 3 years ago

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

twrichards commented 3 years ago

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

    const gqlSchema = appsync.Schema.fromAsset(
      join(__dirname, "../shared/graphql/schema.graphql")
    );