aws-amplify / amplify-category-api

The AWS Amplify CLI is a toolchain for simplifying serverless web and mobile development. This plugin provides functionality for the API category, allowing for the creation and management of GraphQL and REST based backends for your amplify project.
https://docs.amplify.aws/
Apache License 2.0
82 stars 71 forks source link

AppSync conditional mutation not working in mock #1450

Open djwood opened 1 year ago

djwood commented 1 year ago

How did you install the Amplify CLI?

npm

If applicable, what version of Node.js are you using?

v18.15.0

Amplify CLI Version

11.1.1 (also tested 10.6.2)

What operating system are you using?

mac, openJDK 20.0.1

Did you make any manual changes to the cloud resources managed by Amplify? Please describe the changes made.

Using AWS CLI and without any manual changes.

Describe the bug

A valid conditional mutation in Appsync Console will throw exception in mock api. This is due to a malformed DynamoDB execution statement that is missing the "expressionValues" object in the "condition" block. Interesting to note that the local mock VTLs are identical to the Appsync Console VTLs.

GraphiQL error response:

{
  "data": {
    "updateTodo": null
  },
  "errors": [
    {
      "message": "Invalid ConditionExpression: An expression attribute value used in expression is not defined; attribute value: :and_1_isHidden_eq",
      "errorType": "DynamoDB:ValidationException",
      "data": null,
      "errorInfo": null,
      "path": [
        "updateTodo"
      ],
      "locations": [
        {
          "line": 2,
          "column": 3,
          "sourceName": "GraphQL request"
        }
      ]
    }
  ]
}

In the Mock console:

Error while executing Local DynamoDB
{
    "version": "2018-05-29",
    "operation": "UpdateItem",
    "key": {
        "id": {
            "S": "todo-1"
        }
    },
    "update": {
        "expression": "SET #updatedAt = :updatedAt, #isHidden = :isHidden",
        "expressionNames": {
            "#updatedAt": "updatedAt",
            "#isHidden": "isHidden"
        },
        "expressionValues": {
            ":updatedAt": {
                "S": "2023-05-09T23:11:31.843Z"
            },
            ":isHidden": {
                "BOOL": true
            }
        }
    },
    "condition": {
        "expression": "(attribute_exists(#id) AND #isHidden = :and_1_isHidden_eq)",
        "expressionNames": {
            "#id": "id",
            "#isHidden": "isHidden"
        }
    }
}
ValidationException: Invalid ConditionExpression: An expression attribute value used in expression is not defined; attribute value: :and_1_isHidden_eq

As you can see, the "expressionValues" object is missing in the "condition" object.

Expected behavior

A valid conditional mutation should work in mock mode.

Reproduction steps

  1. Add GraphQL API: amplify add api
  2. Edit schema.graphql:
    type Todo @model {
    id: ID!
    name: String
    isHidden: Boolean
    description: String
    }
  3. Invoke Amplify mock: amplify mock
  4. Invoke conditional mutation in GraphiQL:
    mutation MyMutation {
    updateTodo(
    input: {id: "todo-1", isHidden: true}
    condition: {isHidden: {eq: false}}
    ) {
    id
    name
    isHidden
    }
    }
  5. See error in GraphiQL response and mock console.

Project Identifier

No response

Log output

``` # Put your logs below this line ```

Additional information

No response

Before submitting, please confirm:

AnilMaktala commented 1 year ago

Hey @djwood 👋, Thank you for reporting this issue. Based on the reproduction steps provided, we were able to replicate the issue and have consequently labeled it as a bug for our team to further evaluate.

image